Java Optional โ avoiding NullPointerException properly
Optional creation, of, ofNullable, empty, isPresent, get, orElse, orElseGet, map, flatMap, filter, ifPresent, Optional anti-patterns, return type usage
Optional
Optional<T> is a container that explicitly signals a value may or may not be present. It forces callers to handle the absent case at compile time, unlike null which fails silently at runtime.
Creating Optional
Optional present = Optional.of("hello"); // throws NullPointerException if null
Optional nullable = Optional.ofNullable(null); // safe with null input
Optional empty = Optional.empty();
Consuming Optional
Optional name = findUser(42).map(User::getName);
// Unsafe โ throws NoSuchElementException if empty
String bad = name.get();
// Safe alternatives
String safe = name.orElse("Anonymous");
String computed = name.orElseGet(() -> generateDefault());
String thrown = name.orElseThrow(() -> new UserNotFoundException(42));
// Chain transformations without unwrapping
name.filter(n -> n.length() > 3)
.map(String::toUpperCase)
.ifPresent(System.out::println);
flatMap โ Nested Optional
Optional city = findUser(42)
.flatMap(user -> user.getAddress())
.map(Address::getCity); // avoids Optional>
Anti-patterns: Do not use Optional as a field type โ poor serialization support. Do not use it as a method parameter โ it clutters call sites and forces callers to wrap values. Use Optional only as a return type for methods where absence is a meaningful, expected outcome.
Do not use Optional to wrap every return type defensively โ it adds allocation overhead and makes the API noisier. Reserve it for methods where absence is a meaningful, expected outcome: lookup by key, finding the first matching element, or reading an optional configuration value.
