library
beginnerNull Safety: Optional Best Practices
Use Optional correctly as a return type and avoid the anti-patterns that make code worse.
Optional<T> (Java 8) is a container that either holds a value or is empty. It forces callers to explicitly handle the absence of a value.
Optional = a gift box that might be empty. Instead of handing someone a gift that might not exist (null), you hand them a box. They can feel the weight (isPresent), open it safely (orElse), or decide what to do if it's empty (orElseThrow).
Key Concepts
1
Creation:
- Optional.of(value): throws NPE if null
- Optional.ofNullable(value): empty if null
- Optional.empty(): explicitly empty
2
Transformation (monadic operations):
- map(fn): transform the value if present
- flatMap(fn): transform when fn returns Optional (avoids Optional<Optional<T>>)
- filter(predicate): keep value only if predicate matches
- or(() -> fallback): chain alternatives (Java 9)
- stream(): convert to 0-or-1 element stream (Java 9)
3
Terminal:
- orElse(default): return default if empty
- orElseGet(supplier): lazy default
- orElseThrow(): throw if empty
- ifPresent(consumer): act on value if present
- ifPresentOrElse(action, emptyAction): handle both cases (Java 9)
4
Best practices:
- Use as return type: Optional<User> findUser(String id)
- Never use as method parameter, field, or collection element
- Never call .get() without isPresent() — use orElse/orElseThrow instead
- Don't use Optional.of() when value might be null — use ofNullable
- Prefer method chaining over if (opt.isPresent())