Non-null is the Default

Non-null is the Default

Using annotations to make Java’s type system better

IntelliJ warns about potential NullPointerExceptionsIntelliJ warns about potential NullPointerExceptions

The @Nullable imposes an obligation on the consumers of the value: they must prepare for it to be null. But what happens when I’m the one producing the value? Suppose that I’m calling the method above.

This doesn’t look broken!This doesn’t look broken!

We’ve got a problem. If the file doesn’t exist this method passes a null source to printLines() and that will trigger a crash. We need the opposite of @Nullable: an annotation that alerts us if we put null somewhere it doesn’t belong.

The JSR-305 annotations package has this and it’s called @Nonnull. We just need to put it everywhere that we don’t already have @Nullable.

@Nonnull everywhere!@Nonnull everywhere!

Being explicit about which values mustn’t be null lets our tools warn us if we make a mistake.

Yay, broken code looks broken.Yay, broken code looks broken.

Unfortunately, @Nonnull everywhere is boilerplate everywhere. This extra code distracts from the real problems we’re solving. Thankfully, there’s a solution: JSR 305’s @ParametersAreNonnullByDefault indicates that everything in an entire package is non-null unless otherwise specified. Apply it by creating a package-info.java file in each package.

Copy and paste our package-info.java to get started!Copy and paste our package-info.java to get started!

By coupling @ParametersAreNonNullByDefault with @Nullable we’re able to use null safely.

If you’re defining Kotlin APIs you don’t need non-null annotations. The entire language is non-null by default and only types suffixed with ? can be null.

If you’re calling Java APIs from Kotlin, you need to be a bit more careful. The language doesn’t yet honor @ParametersAreNonnullByDefault when it’s used to call Java APIs. JetBrains is tracking this and hopefully it’ll be supported in a future release.

Today we’re releasing OkHttp 3.8, a library where everything is non-null by default. The update is more strict about incoming nulls in three methods. Please read the change log to avoid any surprises!

This post is part of Square’s “Square Open Source ♥s Kotlin” series.