Null Safety in Kotlin

The definitive guide to handling null references in Kotlin

Anirban Chatterjee
Jun 30, 2020 · 5 min read

Overview

In this article, we’ll look into the null safety in Kotlin.

Nullable and Non-Nullable Type

Kotlin aims at eliminating the risk of NullPointerException. It distinguishes between nullable and non-nullable references as a part of its type system.

var country: String = "India"country = null //compilation error
var city: String? = "Kolkata"city = null
val a : String = country.lengthval b : String = city.length //compilation error

Working With Nullable Types

Null Check

We can use the if-else expression to explicitly check for nullable variables. This option works only where the variable is immutable. Depending on the complexity of the conditions, this can also lead to nested expressions.

val city: String? = "Kolkata"
return if (city != null) {
city.length
} else {
null
}

Safe Call Operator ( ?. )

Kotlin has a safe call operator(?.) to handle null references. This operator executes any action only when the reference has a non-null value. Otherwise, it returns a null value. The safe call operator combines a null check along with a method call in a single expression.

val country: String? = "India"
assertEquals(5, country?.length)
val city: String? = null
assertNull(city?.length)
val country: Country? = Country(City("Kolkata", "003"))
val code: String? = country?.city?.code
assertEquals("003", code)
val country: Country? = Country(null)
val code: String? = country?.city?.code
assertNull(code)

Using let() Method

We can use the let() method along with the safe call operator to act on a non-nullable variable:

val cities: List<String?> = listOf("Kolkata", null, "Mumbai")
var name: List<String?> = emptyList()
for (city in cities) {
city?.let { name = name.plus(it) }
}
return name
assertEquals(2, name.size)

Using also() Method

We can use the also() method to execute additional operations like logging and printing of the non-nullable variables. This method can be used in a chain with let() or run() method.

val cities: List<String?> = listOf("Kolkata", null, "Mumbai")
var name: List<String?> = emptyList()
for (city in cities) {
city?.let {
name = name.plus(it)
it
}
?.also { println("Logging the value: $it") }
}
return name
assertEquals(2, name.size)

Using run() Method

We can use the run() method to execute some operations on a non-nullable reference. This method operates using this reference and returns the value of the lambda result:

val countries: List<String?> = listOf("India", null, "Germany")
var name: List<String?> = emptyList()
for (country in countries) {
country?.run {
name = name.plus(this)
this
}?.also { println("Logging the value: $it") }
}
return name
assertEquals(2, name.size)

Elvis Operator ( ?: )

We can use the Elvis operator(?:) to return a default value only if the original variable has a null value. If the left-side expression of the Elvis operator has a non-nullable value, then it is returned. Otherwise, the right-side expression is returned.

val country: Country? = Country(City("New Delhi", null))
val result = country?.city?.code ?: "Not available"
assertEquals("Not available", result)
val country: Country? = Country(City("Mumbai", "002"))
val result = country?.city?.code ?: "Not available"
assertEquals("002", result)
val country: Country? = Country(City("Chennai", null))
val result = country?.city?.code ?: throw IllegalArgumentException("Not a valid code")
assertThrows<IllegalArgumentException> { result }

Not Null Assertion Operator ( !! )

We can use the not-null assertion operator(!!) to explicitly throw a NullPointerException. This operator converts any reference to its non-nullable type and throws an exception if the reference has a null value.

val country: String? = null
val result : Int = country!!.length
assertThrows<NullPointerException> { result }
val country: String? = "India"
val result : Int = country!!.length
assertEquals(5, result)
country!!.city!!.code
country?.city?.code

Nullability in Collections

Kotlin collections are non-nullable by default. To define a collection of nullable types in Kotlin, we have to append question mark(?) to the type declaration:

val countries: List<String?> = listOf("India", null, "Germany", "Russia", null)
var countries: List<String>? = listOf("India", "Germany", "Russia")
countries = null

Filtering Nullable Types

We can filter a list that contains nullable values to return only the non-nullable values using the filterNotNull() method.

val countries: List<String?> = listOf("India", null, "Germany", "Russia", null)
val result: List<String> = countries.filterNotNull()
assertEquals(3, result.size)
assertEquals("Russia", result[2])

Conclusion

In this article, we look into the various ways to handle nullable references in Kotlin.

The Startup

Get smarter at building your thing. Join The Startup’s +800K followers.

Anirban Chatterjee

Written by

Software Engineer | Blogger | Traveler | Football fan | Amateur Photographer

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +800K followers.

Anirban Chatterjee

Written by

Software Engineer | Blogger | Traveler | Football fan | Amateur Photographer

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +800K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store