Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Nullable Types

Basic Concept

To understand the compilation error in Null.kt, you must first understand that the data types we normally use in a Kotlin program are non-nullable. This means that an Int variable or a String variable, for example, cannot have the value null.

This is quite useful. It means we can invoke a method or extension function on an Int, a String or an instance of some other data type with complete confidence, knowing that there is definitely an object there, on which the requested operation can be performed.

However, nulls can also be useful. For example, if a function is not able to generate a sensible return value, it can be useful to signal this by returning a null, rather than by throwing an exception.

Besides, it is actually necessary for Kotlin to support the use of nulls, because Kotlin is supposed to integrate seamlessly with Java, and object references in Java can implicitly be null.

Kotlin addesses this by having a parallel type system, consisting of nullable variants of the standard non-nullable types. These nullable variants have the same name as their non-nullable counterparts, but with a ? appended. Thus Kotlin has Int? to represent nullable integers, String? to represent nullable strings, and so on.

The use of ? as a suffix is a clever mnemonic device. You can think of Int?, for example, as meaning “could be an integer or could be null”, whereas Int means “definitely an integer”.

Caution

It’s important to understand that there is no extra code required here. The Kotlin standard library doesn’t have code to implement the String class, plus additional code to implement the String? class.

Instead, you should think of nullability as a ‘label’ attached to a type declaration to indicate a degree of uncertainty. It means that “a variable of this type might represent the value null instead of a useful value”.

Now we can finally explain why the compilation error in Null.kt occurs. The function readLine() has a return type of String?, meaning it might return a String object or it might return a null. Thus the type of variable input is also String?. The error occurs because printReversed() is expecting a non-nullable string as an argument, but it is being given a nullable string.

The Kotlin compiler is strict about using a value of a nullable type in places where a value of a non-nullable type is expected. It will allow this only if we explicitly check the value first, to make sure that it is not null.

Benefits of Strictness

To understand why Kotlin’s strict requirement for null checks is a good idea, consider what happens in the Java language.

In Java programs, there is always the possibility that an object reference might be null, but the compiler doesn’t require references to be checked before use. If a program attempts to invoke a method on an object but the object reference is null, the result is a runtime error—specifically, a NullPointerException (NPE).

NPEs can always be avoided through more careful programming, but Java developers often aren’t careful enough. Sometimes, an NPE ‘leaks out’ of an application and is embarrassingly visible to users—as in this example from 2018, of an NPE in a banking app:

Example of an NPE in a real Java application (TSB's banking app).

This problem is much less common in Kotlin applications, thanks to the strictness of the Kotlin compiler and the ease with which null checks can be performed.