Kotlin Calling Java: Mind Your nulls

If you’re introducing Kotlin to an existing Java codebase, you’ll probably have places in your code where new Kotlin code has to call existing Java code, or vice-versa. Kotlin’s default behavior for Java interop poses a subtle, but significant safety problem with nullability.

If you have Kotlin code calling Java code with this signature:

    public void addPerson(Person newPerson);

Kotlin doesn’t know if newPerson means Person? or Person in Kotlin, so type-inference treats it as Person!, a platform type of unknown nullability.

What does that mean? It means Kotlin lets you treat newPerson as either nullable or non-null, assuming you know what you’re doing, and making no effort to safety-check your assumptions. This is obviously bad, because if the Java code expects newPerson to always be non-null, this will blow up at runtime, with no warnings from Kotlin.

There’s worse. What happens when Java code calls Kotlin? Given a Kotlin class:

data class Person(val name: String)

Java code can then try to new up a Person as:

    final var person = new Person(name);
    // What happens when name is null?

Which will provoke a NullPointerException from the Kotlin code. Not exactly type-safe, and quite entertaining when it happens in production.

The Workaround

There’s no great fix for this problem. The best workaround I’ve found is to carefully add JSR-305 nullability annotations to Java code that faces Kotlin as the Kotlin-Java interop page suggests, and to be vigilant when reviewing code with Kotlin-Java boundaries.

import javax.annotation.Nonnull;

...

    public void addPerson(@Nonnull Person newPerson);