Java Optional Values

Introduction

Before Java 8 there were only two possible ways to gracefully exit a method when a value is not present, either you return null or throw an exeption. This has changed since Java 8 with the Optional interface.

Java 8 includes the class java.util.Optional out-of-the-box.

Optional Class

Since Java 8 we have a third alternative, Optionals, which can contain an element or nothing. Optional allows us to return an empty result.

The optional library provides two ways to return an empty Optional: Optional.empty() and Optional.ofNullable(nullValue). But do not use Optional.of(value) if a null value is expected to be returned, because in that case it will throw a NullPointerException.

public class MyClass {

	public static Optional<Integer> findMyLuckyNumber(List<Integer> list, Integer luckyNumber) {
		
		if (list.isEmpty()) {
			return Optional.empty();
		}
		
		Integer result = null;
		
		for (Integer value : list) {
			if (value == luckyNumber ) {
				result = value;
			}
		}
		
		return Optional.ofNullable(result);
	}
}
private static final Logger LOGGER = Logger.getLogger(Main.class.getName());

public static void main(String[] args) {
	
	// returns Optional with value
	LOGGER.info(MyClass.findMyLuckyNumber(List.of(2, 5, 9), 9).toString());
	// returns empty Optional
	LOGGER.info(MyClass.findMyLuckyNumber(List.of(2, 5, 9), 1).toString());
	// returns empty Optional
	LOGGER.info(MyClass.findMyLuckyNumber(new ArrayList<>(), 1).toString());
}

Should I always used Optional instead of returning null or throwing an exception? In most of the cases it is recommended to return an Optional, because returning null or throwing an unchecked exception might be ignored by the client, and returning a checked exception forces the client side to write more code. Therefore, if an Optional is returned, the client can decide what to do.

A default behaviour can also be specified when null is returned by appending .orElse(“Empty…”) or orElseThrow(Exception::new). Another alternative is to use .orElseGet(Supplier), which is more efficient than .orElse(), because the value is only retrieved when necessary. Remember that all these options return unwrapped values. Also you can use ifPresent() to run a block of code if the value is present.

Java 9 added three new methods into the Optional class: .or(Supplier<T>), ifPresentOrElse(Consumer, Runnable) and the stream method, which allows you to use Optionals as streams. The main advantage of the first two methods is that now we can return an Optional as default value.

Optional<Integer> defaultValue = Optional.of(99);
Optional<Integer> emptyValue = Optional.ofNullable(null);
// prints 99
System.out.println(emptyValue.or(() -> defaultValue).get());

You can also check if an Optional is empty by calling isPresent(), but since we have the methods mentioned above, you would rather use those for simplicity.

Drawbacks

Returning an Optional is not always the best solution:

Conclusion