Optional represents either one non-null value or no value, making a possibly absent return result explicit in an API.
Java Optional: absence without hidden failure
Absence is not an exception
A lookup can legitimately have no configured reply address. That is different from a failed database connection. Optional can express the first outcome; it should not quietly conceal the second.
The program converts a nullable configured string into Optional, trims it, and rejects a blank value. Mapping a function that returns null yields an empty Optional. The caller then chooses a fallback.
Optional itself should not be null. Returning null from an Optional-returning method forces callers to check two absence mechanisms and defeats the contract.
Choose eager or lazy fallback intentionally
orElse receives a value that Java evaluates before the call. If that value comes from an expensive method, the method runs even when the Optional already contains a value. orElseGet receives a supplier and invokes it only when a fallback is needed.
This distinction affects cost and side effects. A fallback that reads configuration or performs I/O should not run accidentally just because the return type looks convenient.
get throws when the Optional is empty. Chaining get immediately after creating the Optional replaces a null check with another failure. Prefer map, flatMap, ifPresent, or an explicit fallback according to the caller’s intended behavior.
Working program
import java.util.Optional;
public class ReplyAddressLookup {
static Optional<String> configuredAddress(String rawAddress) {
return Optional.ofNullable(rawAddress)
.map(String::trim)
.filter(address -> !address.isEmpty());
}
static String fallbackAddress() {
System.out.println("fallback evaluated");
return "[email protected]";
}
public static void main(String[] args) {
System.out.println(configuredAddress(" [email protected] ").orElseGet(ReplyAddressLookup::fallbackAddress));
System.out.println(configuredAddress(" ").orElseGet(ReplyAddressLookup::fallbackAddress));
}
}Output
[email protected]
fallback evaluated
[email protected]Cost and design choices
The wrapper operations perform a small fixed number of steps; trimming work and possible copying depend on string length. The fallback cost is avoided for the first lookup because the supplier is not invoked.
Optional introduces a representation choice. It is useful for a clear return contract, but turning every object field or method parameter into Optional can add ceremony without clarifying ownership or validation.
A returned Optional cannot say why a value is absent unless the API defines that meaning separately. If callers need multiple failure reasons, use a result type with those reasons instead of collapsing them into empty.
Connected lessons
Continue with Failure handling, Suppliers and mapping, Stream result processing.
Common Mistakes
- Do not return null instead of Optional.empty().
- Do not pass null into Optional.of.
- Do not call get without an established presence guarantee.
- Do not hide infrastructure failures as ordinary absence.
Stream and collector contracts
Continue with Java Collectors.groupingBy: reject or normalize null classifier keys.
