Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
Nullability
A feature that makes Kotlin more valuable is its type system, and the management of nullability.
Kotlin help you to avoid the in-famous NPE (NullPointerException
). You have to understand that
you may have NPE, even with Kotlin, but this will happen if you don't make enough effort.
Kotlin will help you think about how you code in a good way.
In Kotlin, each type is consider non-null
, but each of those types have a derived type nullable. Nullable types
are followed by the ?
character. For example, a non-null
string will be written String
and a nullable one will be
String?
.
// Variable that cannot be `null`
var str: String = "K."
// Variable that can be null
var str2: String?
Dealing with nullable types
Also, Kotlin provides a way to avoid NPE, when calling multiple level of nullable values. In fact, it's not an helper but some compile checks that forbid you to write unsafe code.
As you can have non-null
types, you cannot assign non-null
variables / parameters with null
value.
var str: String = null
// Compilation error
fun strLength(s: String) = s.length
strLength(null)
// Compilation error
Accessing nullable values
For the following sections, let's assume the snippet:
data class Address(val city: String)
data class Person(val firstname: String, val lastname: String?, val address: Address?)
Safe call operator ?.
Safe-calls allow you to call properties or functions from a nullable value. It combines a null
check and an
invocation in a single expression. For example, s?.length
is equivalent to if(s != null) s.length else null
.
So if you are trying to invoke a property or a function upon a null
value, it will use null
as the value, instead
of throwing a NPE
.
Elvis operator ?:
When dealing with null
s you may have to define default values instead of getting a null
. So could write the
following code:
Elvis operator also accept throwing exception in the right side of it.
person.address?.street ?: throw IllegalStateException("For shipping purpose, the street is mandatory")
The let
function
The let
function help you deals with not null values. Precede by the safe-call (?.
), it can help you manipulate
values inside a lambda like:
// If person.address isn't null the let function returns the address.city with uppercase
person.address?.let { it.city.toUpperCase() }
So we could write the following extension function to get the shipping address for a Person: