Blog / November 13, 2017 / 4 mins read / By Suneet Agrawal

Safe calls(?.) vs Null checks(!!) in Kotlin

In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a normal property can’t hold a null value and will show a compile error.

var variable : CustomClass = CustomClass()
variable = null //compilation error

Instead, we can add a ? after the data type of that property which declares that variable as a nullable property

var nullableVariable : CustomClass? = CustomClass()
nullableVariable = null //works fine

In any case, the nullable property requires a null check every time before accessing that property or requires a confirmation from the developer that the estimation of that property won’t be null while accessing it.

variable.someMethodCall() //works fine as the compiler is sure that
                          //the variable can't be null
nullableVariable.someMethodCall() //will highlight compilation error
                                  //as compiler is not sure as
                                  //nullVariable can be null.

There are still few techniques for using or accessing the nullable variable. One of them is safe call ?. and another one is null check !! but before figuring out the difference among both, let’s understand what they are in detail first.

Explicit Null Check

This is the old pattern that we use in every other language, checking the variable if its null or not.

if ( null != nullableVariable) {
 nullableVariable.someMethodCall()
} else {
 // fallback flow
}

Note this exclusive works where ’nullableVariable’ is immutable (i.e. a local property which can’t be altered between the check and the utilization or a member ‘val’ which has a backing field and is not overridable), else it may happen that ’nullableVariable’ changes to null after the check.

If it’s a mutable property, the explicit null check won’t work and the compiler will show the below compilation error.

Smart cast to CustomClass is impossible, because nullableVariable is a mutable property that could have been changed by this time.

Safe Calls (?.)

Another way of using a nullable property is safe call operator ?.

This calls the method if the property is not null or returns null if that property is null without throwing an NPE (null pointer exception).

nullableVariable?.someMethodCall()

Safe calls are useful in chains. For example, if Bob, an Employee, may be assigned to a Department (or not), that in turn may have another Employee as a department head, then to obtain the name of Bob’s department head (if any), we write the following

val departmentHead = bob?.department?.head?.name

Such a chain returns null if any of the properties in it is null.

To perform a certain operation only for non-null values, you can use the safe call operator together with let

val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
 item?.let { println(it) } // prints A and ignores null
}

Elvis Operator (?:)

This one is similar to safe calls except the fact that it can return a non-null value if the calling property is null even

val result = nullableVariable?.someMethodCall()
                       ?: fallbackIfNullMethodCall()

The Elvis operator will evaluate the left expression and will return it if it’s not null else will evaluate the right side expression. Please note that the right side expression will only be called if the left side expression is null.

Note that, since throw and return are expressions in Kotlin, they can also be used on the right-hand side of the Elvis operator. This can be very handy, for example, for checking function arguments

fun foo(node: Node): String? {
 val parent = node.getParent() ?: return null
 val name = node.getName() ?: throw IllegalArgumentException("name expected")
 // …
}

The !! Operator

This operator is used to explicitly tell the compiler that the property is not null and if it’s null, please throw a null pointer exception (NPE)

nullableVariable!!.someMethodCall()

this code will work fine if ’nullableVariable’ is not null else it will throw an NPE.

Difference between ?. and !!

  • The basic difference while using ?. and !! is if you want to separate a normal flow of var property having a ’non-null’ value with ’null’ value flow use ?.
  • But if you are sure that the var property value is not null use !! instead of ?.
  • Also, ?. can be used to return or throw a different kind of exceptions using ?: at the end of the expression but !! will only throw an NPE.
Comments