8.5 The Optional<T> Class & Null Safety
← Back to Chapter 8: Java 8 Features
Introduced in Java 8, java.util.Optional<T> is a single-value container designed to explicitly represent the presence or absence of a value without resorting to error-prone null references.
What is Optional Class?
A value that may or may not be present.
It helps reduce situations where you get NullPointerException because a value is null.
Without Optional
String name = user.getName();
if (name != null) {
System.out.println(name);
}
With Optional
Optional<String> name = Optional.ofNullable(user.getName());
name.ifPresent(System.out::println);
Think of Optional as a box that may contain a value or may be empty.
Creating Optional Instances
Optional.of()
Use when you are sure the value is not null.
// 1. Definite non-null value (throws NPE immediately if value is null)
Optional<String> opt1 = Optional.of("CodeWithSarvy");
If you pass null. It throws NullPointerException.
Optional.ofNullable()
Use when the value may be null.
// 2. Value may or may not be null
Optional<String> opt2 = Optional.ofNullable(fetchNullableUsername());
If name is null, you get an empty Optional, not an exception.
of() → value must NOT be null
ofNullable() → value MAY be null
Optional.empty()
Creates an empty Optional.
// 3. Explicit empty container
Optional<String> opt3 = Optional.empty();
Optional class method
| Method | Description |
|---|---|
isPresent() | Returns true if there is a value present, otherwise false. |
isEmpty() | Returns true if the Optional is empty, otherwise false. (Introduced in Java 11) |
ifPresent(Consumer<? super T> action) | If a value is present, performs the given action with the value, otherwise does nothing. |
ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) | If a value is present, performs the given action; otherwise, performs the empty-based action. (Introduced in Java 9) |
get() | If a value is present, returns the value, otherwise throws NoSuchElementException. (Note: Using this without checking is generally discouraged). |
orElse(T other) | Returns the value if present, otherwise returns the specified other default value. |
orElseGet(Supplier<? extends T> supplier) | Returns the value if present, otherwise invokes the supplier and returns the result of that invocation. |
orElseThrow() | Returns the contained value if present, otherwise throws NoSuchElementException. (Introduced in Java 10) |
orElseThrow(Supplier<? extends X> exceptionSupplier) | Returns the contained value if present, otherwise throws an exception created by the provided supplier. |
filter(Predicate<? super T> predicate) | If a value is present and matches the predicate, returns an Optional describing the value, otherwise returns an empty Optional. |
map(Function<? super T, ? extends U> mapper) | If a value is present, applies the mapping function to it, and returns an Optional describing the result if non-null. |
flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) | If a value is present, applies the mapping function to it (which returns an Optional), and returns that Optional directly. |
or(Supplier<? extends Optional<? extends T>> supplier) | If a value is present, returns the Optional; otherwise, returns an Optional produced by the supplying function. (Introduced in Java 9) |
stream() | If a value is present, returns a sequential Stream containing only that value, otherwise returns an empty Stream. (Introduced in Java 9) |
equals(Object obj) | Indicates whether some other object is "equal to" this Optional. |
hashCode() | Returns the hash code value of the present value, or 0 if no value is present. |
toString() | Returns a non-empty string representation of this Optional suitable for debugging. |