Avoid null pointer exceptions by being explicit about nullability in Kotlin
Kotlin’s type system aims to avoid null references by making it explicit when a variable can be null. In Kotlin by default variables are non-nullable i.e. setting a variable to null
is an error.
val name: String = null // is an error because String is non-nullable
If you want a variable to be nullable you must add a question mark ?
to the end of the type.
val name: String? = null
Now any attempt to use name
that could result in a NullPointerException
e.g. println(name.uppercase())
will be an error forcing you to handle the null correctly.
Default Values
Often you will want to check for a null and replace it was some default value. Kotlin provides the Elvis operator ?:
to do this concisely.
val name: String = nullableName ?: "Default"
When the expression on the left side of ?:
is not null that value will be used otherwise the expression on the right side will be used. This is equivalent to the following in Java.
String name = nullableName;
if (nullableName == null) {
name = "Default";
}
Safe Call Operator and Method Chaining
Kotlin also provides the safe call operator ?.
to access properties and perform operations on nullable values. The safe call will behave the same as a .
when the value is non-null and “circuit break” returning null when the value is null.
val nameLength: Int? = nullableName?.length
The safe call operator can be chained e.g. order?.customer?.address?.postcode
will return null if any of the values in the chain are null.
This is equivalent to the following in Java. The chained example is omitted as the Java version becomes increasingly unwieldy as the chain lengthens.
Integer nameLength = null;
if (nullableName != null) {
nameLength = nullableName.length;
}
Forced Unwrapping on a Nullable
On some rare occasions, you know better than the compile and are certain that the value is not null in this case you can use the not-null assertion operator !!
. This will convert the value to a non-nullable type if it can or throw a NullPointerException
if the value is null
.
val nameLength: Int = nullableName!!.length
This is essentially how Java works except Java lets you do this implicitly. You’ll quickly become slightly unnerved by the !!
operator as it usually comes back to bite you.
Comparison to Optional in Java
Nullable types are similar to Optional
s in Java i.e. they represent the absence of a value. The use of Optional
is recommended in cases where you’d return null
to represent no value returned.
The Elvis operator is similar to orElse
.
optional.orElse("Default");
The safe call operator is similar to map
.
optional.map(s -> s.length());
The not-null assertion operator is similar to get
without checking whether a value is present.
optional.get();