Nullability is a Kotlin feature that’s intended to help you eliminate NullPointerExceptions in your code. We all know that null pointer exceptions are bad, and the features I introduce in the following lessons are Kotlin’s way of eliminating them.
Two rules about using null values:
Before you move into the following lessons, it’s worth mentioning that I like to think that there are two rules about using null values in Kotlin:
- Never use null values!
- When you’re forced to use null values — such as by using an old Java library — use Kotlin’s nullable types and the operators shown in the next few lessons.
With that point made, let’s jump into nullable types.
Null type approach
Nullable types are an approach in Kotlin to help you eliminate null values and null pointer exceptions (the dreaded NullPointerException ).
Here are the main concepts.
A variable of type String can never be null
A variable of the nullable type String? can be null
The operations that can be performed on nullable types are very limited.
I use String in those statements, but the same things can be said about every other type, including Int , Float , Person , etc.
Standard types can’t be null
Variables that are instances of standard Kotlin types can’t contain null values:
val> val s: String = null
error: null can not be a value of a non-null type String val s: String = null
>>>val i: Int = null
error: null can not be a value of a non-null type Int val i : Int = null
Similarly, variables that are instances of custom types can’t be null either:
>class Person (var name: String)
>val p: Person = null
error: null can not be a value of a non-null type Line_3.Person val p: Person = null
A nullable type is a variation of a type that permits null values. You declare a type to be nullable by adding a question mark after it:
var s: String? = null
This simple addition to your type allows your variable to contain null values. Notice that no exceptions are thrown in the REPL when you declare a nullable type:
>>>var s: String? = null
>>>var i: Int? = null
>>>var p: Person? = null
Also notice that I intentionally declare those variables as var fields. I do this because they’re declared with null values, but at some point later in their lifetime they’ll presumably contain more useful values.
Where you’ll use nullable types
You’ll use and encounter nullable types in several areas:
- Variable assignment
- Function parameters
- Function return values
- Converting a nullable type to its non-nullable equivalent
Because a nullable type can be null , in order for them to be safe to work with, the methods you can call on them are intentionally very restricted. As you can imagine, if you try to call a function like length() on a null string, it will throw a null pointer exception. Therefore, a String? instance doesn’t have a length property:
>>>var s: String? = “fred”
error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?