Get up to 80 % extra points for free! More info:

Lesson 6 - Type system: Null safety in Kotlin

In the previous exercise, Solved tasks for Kotlin lesson 5, we've practiced our knowledge from previous lessons.

Lesson highlights

Are you looking for a quick reference on null safety in Kotlin instead of a thorough-full lesson? Here it is:

Declaring and printing a nullable variable:

var maybeNumber: Int? = null
println(maybeNumber)

Working with a nullable variable safely using a condition:

var maybeNumber: Int? = 15
if (maybeNumber != null) // the condition allows to perform * 2 below
    println(maybeNumber * 2)
else
    println("No value to work with")

Alternative null condition using ?.let:

var maybeNumber: Int? = 15
maybeNumber?.let { println(maybeNumber * 2) } // won't be called if null

Forcing the value of a nullable variable using the !! operator (unsafe):

var maybeNumber: Int? = 15 // if this is null, the program crashes
println(maybeNumber!! * 2)

Safe calling:

var name: String? = null
println(name?.length) // prints null, doesn't crash

Using the Elvis operator ?::

var greeting: String? = "Hello world"
println(greeting?.length ?:  0) // 0 is used when greeting is null

Would you like to learn more? A complete lesson on this topic follows.

Are you looking for a quick reference on creating a Java SE project in the NetBeans IDE instead of a thorough-full lesson? Here it is:

In the previous lesson, Solved tasks for Kotlin lesson 5, we learned how to write less code using loops. Now we're going to finally explain the concept of null safety, which is very important in Kotlin. We'll talk about what all the exclamation marks in source code mean. We've already stumbled across a few, and although it may be a little complex concept to start with, it's better to understand at least a little bit what it's all about.

The null value concept

Programming languages must somehow deal with a situation where a variable has no value. We often encounter this problem with functions which hasn't been executed properly. For example, if a number couldn't be retrieved from the console, the output shouldn't be a number but rather an "empty" value. If Kotlin returned the 0 or -1 value in this case, we wouldn't be sure whether the number indicates it wasn't possible to read it or the user had entered 0 or -1. For this purpose, a special null value was introduced, which safely indicates that a variable is empty.

If we create a standard variable in Kotlin, we can't assign the null value to it:

// This code won't work
var number = 15
number = null // This line will cause an error

That's because someone may not be expecting null there. In order to assign null to a variable, we must declare the variable as nullable first.

Nullable types

A nullable type can be seen as kind of a box that wraps an ordinary variable. The box always exists, but when opened, the value is either there or it's empty. To create a nullable type, we place a question mark ? after the data type of the variable. Let's try it:

var maybeNumber: Int? = 15
maybeNumber = null

The code was compiled successfully and the maybeNumber variable is now empty, even though it's a number. That sounds good, right?

There's however a problem that a lot of other programming languages failed to deal with. We shouldn't be able to work with the maybeNumber variable as with a normal variable. If we wrote:

var maybeNumber: Int? = 15
maybeNumber = null
println(maybeNumber * 2)

and the program would be compiled, it could cause a runtime crash in the case of maybeNumber being empty. Of course, we can't multiply "empty" by two. If we tried to write such a program, you'd find that it won't compile. Similarly, Kotlin wouldn't let us access a method or property of a nullable type. You can try yourself that the following code won't compile because of printing the second string's length:

var s1 = "Hello"
var s2: String? = "World"
println(s1.length)
println(s2.length)

You've probably guessed that Kotlin doesn't belong to languages that can't deal with this problem :)

Null safety

The mechanism checking how we use nullable type during the compilation is called null safety. There are several ways to use a nullable variable. Let's try them out one by one.

The !! operator

Let's start with the most silly one which we've been already using in this course, so that the amount of information wasn't that overwhelming. Using the !! operator we can degrade Kotlin to the level of older languages such as e.g. Java and bypass the null safety checking. Everything will work unless the variable is null:

var maybeNumber: Int? = 15
println(maybeNumber!! * 2)

The output:

30

If it's empty though, the whole application will crash:

var maybeNumber: Int? = 15
maybeNumber = null
println(maybeNumber!! * 2)

Since we wouldn't even notice this mistake during the compilation, we won't be using the solution with !! much.

Conditions

A bit smarter solution is to work with nullable types in a condition checking the null value. Since we can avoid application crashes like this, Kotlin will allow us to compile the program:

var maybeNumber: Int? = 15
if (maybeNumber != null)
    println(maybeNumber * 2)
else
    println("The entered value isn't a number")

Safe calling

You surely guessed that there are better solutions then writing null conditions over and over. Using the ?. operator (question mark, dot) we'll either get the given property or null will be returned if the variable is empty.

?.let

If we used safe calling together with the let keyword, the code in the braces would be executed only if the variable contains a non-null value:

var maybeNumber: Int? = 15
maybeNumber?.let { println(it) }

The it keyword in the block contains the value. If maybeNumber was null, the program would compile and the printing wouldn't be executed.

The ?. chaining

We only use this functionality if we want to ask through a chain of properties, for example:

student?.teacher?.superviser?.name

The expression above will either return the name of the school principal (the supervisor of the student's teacher) or null if any expression part is empty. We save a lot of conditions like this, but we have to remember that we still end with a nullable type, even it's just one.

We could safely assign like this as well without the need for additional conditions:

student?.teacher?.supervisor?.name = "Seymour Skinner"

The Elvis operator

The Elvis operator in Kotlin - Kotlin Basic Constructs

I don't think it's necessary to explain the name origins here :) We use Elvis along with the ?. operator. It let us ask whether the value in a nullable variable is null and use a default value instead. Again, let's try it on our example:

var maybeNumber: String? = "Hello world"
println(maybeNumber?.length ?:  0)

On the right side of the Elvis operator, we can also use return or invoke exceptions (see further courses).

For each way of handling the null values, when the value is null, other expressions (methods) meant for the non-null scenario, won't be executed.

In the next lesson, Arrays in Kotlin, we'll talk about arrays.


 

Previous article
Solved tasks for Kotlin lesson 5
All articles in this section
Kotlin Basic Constructs
Skip article
(not recommended)
Arrays in Kotlin
Article has been written for you by Samuel Kodytek
Avatar
User rating:
1 votes
I'm intereseted in JVM languages and Swift
Activities