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

Null safety is one of the best features of Kotlin. If you are familiar with Java, then must have encountered with NullPointerException and to remove this or in other words, we can say that to safely deal with this NullPointerException, the developers of Kotlin introduced Null safety. So, in Kotlin, a normal property can’t hold a null value. If you are doing so then you will get compile-time error.

We can’t use the following syntax in Kotlin:

var name: String = "MindOrks"
name = null //compilation error
// other way
var name: String = null //compilation error

To use or set some variable to null value, we need to append a ? sign to the type of the variable as shown below:

var name: String? = "MindOrks" //no error
name = null //no error
// other way
var name: String? = null //no error

So, it becomes necessary to check if the property that you or any other developer is going to use is null or not. If it is null then you should show some relevant error message and if it is not null then you can do the operation that you want to perform on that property. The very common and mostly used method of checking the nullability is by using if-else :) Yes, you guess it right. Following is the code that is in your mind:

if(name != null) {
    print("Name is : $name")
} else {
    print("Please enter a valid name")
}

Yeah, this method can be used for checking the null values. But what if there are so many variables and you need to check if they all are null or not? You have to write a number of if-else statements for the same :( Don’t be sad, you need not write if-else statements.

In Kotlin, we have Safe calls(?.) and Null checks(!!) for the same work. Let’s see how we can use them and what’s the difference between these two.

Safe call (?.)

Before diving into safe calls, let’s take an example. As you all know that in MindOrks, we provide training on Android, Kotlin and Data Structure. So, suppose we are having one database that stores all the students enrolled in a particular course. Now, we at MindOrks decided to distribute some goodies to the students enrolled in our courses but the goodies are course-specific i.e. we have different goodies for Android, Kotlin and DS. In general, it is possible that a student enrolled in Android batch is not enrolled in DS batch. So, before distributing the goodies we need to check if the student is enrolled (not null) in a particular batch or not(null).

For example, a student "A "is in the DS batch(and not in Android) so, the value of student A in Android is null(as he is not in Android batch). Now if we want to give goodies of Android batch to student A then it will show NullPointerException because the student is of DS batch and we are giving goodies of Android batch. So bad :(

studentA.giveGoodies() //will show compilation error

So, to handle these type of situations, we use Safe calls(?.). The safe call operator ?. will call the method giveGoodies() only when the value of studentA is not null otherwise it will return null. So, we will first check if the student is of Android batch or not. If he is not enrolled in the Android batch then null will be returned i.e. Android goodies will not be given to that student and if he is enrolled in the Android batch then we will give Android goodies to him. So, the final code will be:

studentA?.giveGoodies() 

Safe calls are generally used in chains. For example, if you want to find the instructor name of a particular student A enrolled in some course (or not enrolled) then you can do so by:

studentA?.courseName?.instructor?.name 

If any of the value is null i.e. if either of studentA, courseName, instructor is null then the whole expression will return null. In other words, to get the name of instructor, there must be some student(A) and that student must be enrolled in some course having some instructor otherwise we will get null.

Null checks(!!)

The null check operator !! is used to inform the compiler that the property or variable is null or not. If it is null then it will throw some NullPointerException. So, if we are calling the giveGoodies() method and the value of studentA is not null the following code will work fine otherwise we will get a NullPointerException:

studentA.giveGoodies() //works fine if studentA is not null

So, be sure that if you are using !! then you must use some not null values.

The basic difference between the Safe call and Null check is that we use Null checks (!!) only when we are confident that the property can’t have a null value. And if we are not sure that the value of the property is null or not then we prefer to use Safe calls(?.).

Another thing that can be noted here is that if you are using Null checks (!!) then you will get only NullPointerException(if any) but Safe checks (?.) can be used to generate various other types of error or exceptions also.

So, that’s all about Null checks and Safe checks. Hope you learned something new today.

Do share this blog with your fellow developers to spread the knowledge. You can read more blogs on Android on our blogging website.

Apply Now: MindOrks Android Online Course and Learn Advanced Android

Happy Learning :)

Team MindOrks!