Optional
Optional<T> is a container object that either holds a non-null value or is empty. Added in Java 8, it was designed as a better return type than null for methods that may not produce a result β forcing the caller to think about the empty case at compile time.
Creating and consuming
Optional<User> findById(long id) {
return Optional.ofNullable(db.find(id)); // null β empty, non-null β present
}
Optional<User> u = findById(42);
if (u.isPresent()) {
System.out.println(u.get().getName());
}
// Idiomatic:
u.ifPresent(user -> System.out.println(user.getName()));
String name = u.map(User::getName).orElse("Unknown");
u.orElseThrow(() -> new NotFoundException("user " + 42));
Chaining
Optional<String> city = findById(42)
.map(User::getAddress)
.map(Address::getCity);
When to use Optional
- Return type β for methods where absence is a normal outcome (lookups, searches).
- Stream operations β
findFirst,findAny,reducereturnOptional.
When NOT to use Optional
- Field types β don't store an
Optionalin a class field. Use nullability annotations or a more specific empty representation. - Method parameters β overload the method or use a required parameter;
Optionalas a parameter is awkward for callers. - Collections β return an empty
List/Set, notOptional<List>.