null is a smell in Java that we can’t avoid all the time. If a function that returns an object doesn’t have anything to return at times, then the solution in Java is to return null. This unfortunately leads to an accidental NullPointerException if the caller of the function doesn’t—that is, forgets to—perform an explicit null check. In more recent versions of Java, Optional is used as a solution to this issue, but this approach has three disadvantages. First, the programmer has to use Optional and the compiler won’t force that. Second, Optional involves a small overhead to wrap the object’s reference, or an empty null reference, when there’s no object. Third, a programmer may still return null instead of an instance of Optional and the Java compiler won’t complain. Kotlin avoids these issues and at the same time offers great compile-time support to ensure that necessary null check is done by the programmer.

We’ll first discuss why null references are generally not pleasant to use. Then we’ll see how the Kotlin compiler doesn’t permit assigning null to any arbitrary reference and requires the references that can accept null to be a special nullable type. Then we’ll look at nice operators that Kotlin provides to safely and conveniently dereference nullable references, with full compile-time verification that necessary null checks are done. Finally, we’ll look at how the when expression interplays with null checks.

null is a smell

Effective Java, Third EditionJoshua Bloch. Effective Java, Third Edition. Addison-Wesley, Boston, MA, 2018, suggests that if a function is returning a collection but at runtime there’s nothing to return, then we should return an empty collection instead of null. That’s because the receiver of the result will otherwise fail and will have to perform an explicit null check to avoid the issues. Good advice.

What if the result of a function is an object and not a collection? The traditional solution in Java was to return null if there’s nothing to return as reference, and a more recent recommendation is to return Optional<T>. These solutions present a few issues though.

It’s not possible, in Java, to prevent a programmer from returning null from a method that expects a reference to be returned. Programmers have to opt in to use Optional<T>, and it’s confusing when and where to use it. In addition, with Optional<T> there’s extra overhead just for the sake of avoiding null.

Kotlin handles this situation safely, elegantly, and gracefully. To begin with, assigning null to a non-nullable reference or returning null where the reference type is non-nullable will result in a compilation error.

Here’s a piece of code that will make the Kotlin compiler complain:

Get hands-on with 1400+ tech skills courses.