Java 11 Cookbook
上QQ阅读APP看书,第一时间看更新

Getting ready

The Optional class is a wrapper around a value, which can be null or a value of any type. It was intended to help to avoid the dreaded NullPointerException. But, so far, the introduction of Optional helped to accomplish it only to a degree and mostly in the area of streams and functional programming.

The vision that motivated the creation of the Optional class was to call the isPresent() method on an Optional object and then apply the get() method (to get the contained value) only when the isPresent() method returns true. Unfortunately, when one cannot guarantee that the reference to the Optional object itself is not null, one needs to check it in order to avoid NullPointerException. If so, then the value of using Optional diminishes, because with even less amount of code writing we could check for null the value itself and avoid wrapping inside Optional whatsoever? Let's write the code that illustrates what we have been talking about.

Let's assume that we would like to write a method that checks the lottery result and, if the ticket you have bought with your friend wins, calculates your 50% share. The traditional way to do it would be:

void checkResultInt(int lotteryPrize){
if(lotteryPrize <= 0){
System.out.println("We've lost again...");
} else {
System.out.println("We've won! Your half is " +
Math.round(((double)lotteryPrize)/2) + "!");
}
}

But, to demonstrate how to use Optional, we will assume that the result is of the Integer type. Then, we also need to check for null, if we are not sure that the passed-in value cannot be null:

void checkResultInt(Integer lotteryPrize){
if(lotteryPrize == null || lotteryPrize <= 0){
System.out.println("We've lost again...");
} else {
System.out.println("We've won! Your half is " +
Math.round(((double)lotteryPrize)/2) + "!");
}
}

Using the Optional class does not help to avoid the check for null. It even requires an additional check, isPresent(), to be added so that we can avoid NullPointerException while getting the value:

void checkResultOpt(Optional<Integer> lotteryPrize){
if(lotteryPrize == null || !lotteryPrize.isPresent()
|| lotteryPrize.get() <= 0){
System.out.println("We lost again...");
} else {
System.out.println("We've won! Your half is " +
Math.round(((double)lotteryPrize.get())/2) + "!");
}
}

Apparently, the preceding usage of Optional does not help to improve the code or make the coding easier. Using Optional in Lambda expressions and stream pipelines has more potential because the Optional object provides methods that can be invoked via the dot-operator and can be plugged into the fluent-style processing code.