From Java to Kotlin, with Love – Part 2

In part 1 of this series we explored some of features of Kotlin that make it an expressive and concise language, compared to classic Java. In this part we will explore how Kotlin deals with null and null safety.

Prior to Java 8, we were left on our own to deal with the dreaded NPE. If you had a chain of calls like this:

object1.getObject2().getObject3().someMethod()

You either have to be prepared to catch an NPE since either object1, object2, or object3 may be null or you need to make sure that none of the references is null. To do that in the classic way you would have to do something pretty verbose like this:

if (object1 != null
 && object1.getObject2() != null         
 && object1.getObject2().getObject3() != null) {         

 object1.getObject2().getObject3().someMethod()
}

Now with Java 8 and the introduction of Optional, you can avoid the checking but the alternative is still somewhat verbose and requires understanding Java lambdas and streams:

object1.flatMap(Class1::getObject2)
 .map(Class2::getObject3).
 .map(Class3::someMethod());

Kotlin adopts the safe navigation operator like other modern languages such as Swift, that started around the same time, and Groovy that preceded both. The Kotlin equivalent of the Java code would be:

object1?.getObject2()?.getObject3()?. someMethod()

Pretty neat and very compact!

What is even neater is that the language forces you to make a conscious decision about how a member is initialized. If a member is initialized in the constructor, and thus can be null for part of the lifecycle of the object, you either have to:

  • Declare the variable as being nullable using a ‘?’ and delegate to Kotlin the compile time checking for proper variable usage.
  • Decorate the declaration with lateinit modifier and take over the responsibility of ensuring that the variable is initialized in time before any usage that may cause an NPE.

One might complain that avoiding the NPE is not always the right thing to do as it might be hiding other issues. Well, if you really want an NPE to be thrown when a reference is null then the ‘!!’ operator is what you need:

object1!!.getObject2()

This line will throw an NPE if object1 is null. Of course, the choice depends on the exact situation, but in all cases Kotlin forces you to make a decision and makes every reference that can be null explicit, therefore turning the runtime problem into a compile time one.

One thought on “From Java to Kotlin, with Love – Part 2

Leave a comment