Optional expresses "a value might be absent" in the type system. Used well it
removes defensive null checks; used poorly it adds ceremony without safety.
Transform, don't unwrap early
Chain map and filter so the absent case flows through untouched. Calling
get() early throws away everything the type gave you.
return repository.findById(id)
.map(User::getEmail)
.filter(email -> email.endsWith("@corp.com"))
.orElseThrow(() -> new AccessDenied(id));Return it, don't store it
Optional is a return type for methods that may find nothing. It is not meant
for fields or method parameters.
Optional<User> findById(String id); // good
// private Optional<String> name; // avoid as a fieldTakeaways
- Never call
get()without checkingisPresent()— useorElseororElseThrow. - Do not use
Optionalfor collections; return an empty list instead. - Prefer
orElseGetoverorElsewhen the fallback is expensive to compute.
Treat Optional.of(null) as a bug — it throws immediately. Use ofNullable
when the value may legitimately be null.