All topics
library
beginner

Null 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())