Null Safety

Kotlin’s type system is aimed at eliminating the code’s risk of null reference because it is a very common and easily produceable error. NullPointerException is a very common type of error or exception easily encounterd by a programmer while programming in java or similar language. The main drawback of NullPointerException is that it is not detectable during compile time and it is thrown only during runtime wich causes application failure or system crashes. Kotlin compiler also throws NullPointerException when it detects a null reference.

NullPointerException’s can be cause due to one of the following reasons

  • Explicit call to throw NullPointerException()
  • Use of the not-null assertion operato(!!) operator
  • Data inconsistency with respect to initialization e.g. an uninitialized this is passed as an argument.
  • If you try to access a member on a null reference

Nullable and Non-Nullable Types in Kotlin

Kotlin framework has two types of references which can hold null (nullable references) and those which can not hold null(non-null references).

From the example below a variable of type String can not hold null. If we try to assign null to the variable, compiler will throw error.

1
2
var string1: String = "Monday"
    string1 = null // compilation error will be thrown

To allow a variable to hold null value , we have to declare a variable as nullable string, written String?

1
2
3
var string2: String? = "This is nullable"
    string2 = null // ok
    print(string2) //null will be printed

Now, if we want to access the length of the string string1, it guarantees not to throw Null pointer exception, so we can safely say:

1
val len = string1.length

But if we want to access the length of the string string2, that would not be safe, and the compiler reports an error:

1
val len = string2.length         // error: variable 'string2' can be null    
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

Here, null value can be easily assigned to the variable, thats why the compiler throws error. We should use the null safe operator to access the methods on the variable such as length.

Here comes the rescue, use safe call operator

Safe Call operator(?.)

Kotlin has a Safe call operator, ?. that can be used to execute an action on a variable only when the avriable holds as non-null value. Both null-check and method call can be combined in a single expression using Safe call operator.

1
val len = string2?.length

The above expression is equivalent to

1
2
3
4
if(string2 != null) 
        string2.length()
    else
        null 

How to use safe operator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var userName: String? = "Username"
    var fullName: String? = null
  
    println(userName?.toUpperCase()) 
    println(userName?.length) 
    println(fullName?.toUpperCase())

    //output
    USERNAME
    8
    null