Skip to main content

Why null and optional are not the same

·2 mins

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 ifs 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.