Why null and optional are not the same
One argument I hear often as a Java developer is that people consider Optional
basically the same as null
, but they are different, and in this post, I will try to outline why they are different and why you should learn how to use Optional
properly.
The reason for optional #
I’m not going to give a complete background into why optional was invented, as I am in no way privy to that information, but I’d like to think that one of the reasons was that at some point, someone realized that business logic in most applications was 50% null checks. This is obviously bad, considering that business logic needs to be clear and to the point, and having to traverse over null
check after null
check, coupled with if
s and else
is going to clutter up the code as well as your ability to easily read it. In essence, Optional
was invented as a strategy to increase readability.
They-are-the-same-argument #
At first glance they may appear to be the same, for instance, if you look at the example below, it looks eerily similar
Property property = callSomeMethodThatMayReturnNull();
if (property != null) {
doSomething(property);
} else {
doSomethingElse();
}
Property property = callSomeMethodThatReturnOptional();
if (property.isPresent()) {
doSomething(property.get());
} else {
doSomethingElse();
}
In comparing these two, the differences are barely visible, and if you’re writing code like this, it makes absolutely no sense in using Optional
to increase readability.
Why-the-are-not-the-same-argument #
If you’re a proponent that Optional
is just a fancy null check, you probably have a self-satisfied smile on you face right about now, but here’s where it gets interesting. If you couple optional with lambda, the power of Optional
really starts to shine through. Let’s compare the same code again, but this time, let’s use lambda.
Property property = callSomeMethodThatMayReturnNull();
if (property != null) {
doSomething(property);
} else {
doSomethingElse();
}
callSomeMethodThatReturnOptional()
.ifPresentOrElse(
SomethingClass::doSomething,
SomethingElseClass::doSomethingElse);
You may argue that it’s still the same, and logically it is the same, but look at the readability of the second statement, compared to the first it is so much more readable and the syntax is so much more intuitive.