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
Person in Kotlin, so
type-inference treats it as
Person!, a platform type of unknown
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
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.
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);