Kotlin's Null Safety feature

This post is part of a series of posts about why I’m considering Kotlin for my new projects where I would normally choose Java. If you haven’t read the other posts, check them here: Let’s talk about Kotlin?

Igor Leal
4 min readDec 22, 2017

You know when you are accessing the properties of an object but you are afraid of a NullPointerException? You are more than sure that your business rules don’t allow some properties to be null, like a person’s name, or its document… But, since you are afraid of the NullPointer, because you never knows what kind of instance might come to the point of your code. Some weird code might initialize a person without name without knowing that this i wrong. That leaves your Java code with a lot of

if (person.getName() != null) {
return person.getName().trim();
}

First, you end up writing a lot of useless checks and your code becomes really ugly. That’s where Kotlin’s Null Check comes to help us.

When you create a class with properties, you define if they are nullable or not. That leaves us with two kind of properties, a nullable and a non-null. Let’s suppose I create a class with a nullable and a non-null property:

class Person(val name: String, val photoUrl: String?)

This tells you that a Person instance must have name and might not have photoUrl. The key is when you want to use these properties.

There are two possible ways to instantiate this class:

val igor = Person("Igor", "s3.aws.com/mybucket/photo/igor")
val newUser = Person("New User", null)

If you try this Person(null, null) or any other combination with a null name, your code won’t compile. This leaves you free to access the property without needing a null check. So just run the code below without worrying about a NullPointerException:

igor.name.trim()

But… if you want to call some function on photoUrl you need more details. The following code won’t compile:

igor.photoUrl.trim()
IntelliJ helper when trying to direct access a nullable property

If you are using IntelliJ, which also is created byJetBrains, it will show a compilation error and show you two possible solutions.

Assuming it won't be null at my part of the code

You need to specify if you are sure that at this point photoUrl will never be null. That’s like putting your stamp on the code saying that you guarantee no NPE at this line. If that's the case, you write the code like this:

igor.photoUrl!!.trim()

Be aware, that if at this point photoUrl is null, you will get a NullPointerException. So, if you just go around using this operator without really meaning it, you are wasting this great feature of Kotlin.

Assuming it might be null at my part of the code

On the other hand… you might not assume this risk and say that if the photoUrl is null, you just want to skip the method call. For example:

igor.photoUrl?.trim()

In this case, if photoUrl is null, this expression returns null and does not throw any Exception. If photoUrl is not null, the trim() method is called.

This is really great when you have a chain of properties to call and don't want to write a lot of null checks. You just explicit that the properties might be null:

igor.address?.street?.toUpperCase()

If the instance igor has no address, or has an address without street, the expression just returns null.

Elvis Operator

There is a third way to work with nullable properties. It is called Elvis Operator, which is a binary operator known in computer science. This operator evaluates an expression and returns it if it's not null, otherwise returns the second element. Example:

igor.address ?: "NO ADDRESS"

At this code, if igor has an address, the expression returns the address, otherwise returns the string "NO ADDRESS".

Working with functions that might return null

Besides the fact that a variable must define if it can accept null or not, when your function returns some value you have to follow the same rule.

// Function that returns a String
fun getNameUpperCase(person: Person): String {
return person.name.toUpperCase()
}

// Function that MIGHT return a String
fun getPhotoUrlTrim(person: Person): String? {
return person.photoUrl?.trim()
}

This propagate the whole null safety benefits for any code that calls your function.

Elegant Solution

In the end, it's clear that Kotlin really thought about this problem that we face everyday when programming. And the solution is pretty elegant. You don't need to keep writing unnecessary null checks. As the class owner, you create your class and make it clear to whoever wants to use it how it should be used. And when using someone's class you understand the expected behavior and you access the properties leaving a more readable code.

--

--