Kotlin Null Safety Tutorial: Nullable Types, Safe Calls, Elvis Operator, and Scope Functions


This Kotlin Null Safety tutorial explains how Kotlin prevents NullPointerException using nullable types and null-safety operators. It covers nullable and non-nullable types, the safe call operator, Elvis operator, non-null assertion, and scope functions such as let, run, also, and apply. Each concept is explained with practical examples and best practices to help developers write safe, readable, and robust Kotlin code.

Kotlin Null Safety – Complete Tutorial

Nullable Types

In Kotlin, variables are non-nullable by default. To allow null values, you must explicitly declare a variable as nullable using ?.

Non-Nullable Type


var name: String = "Kotlin"

Nullable Type


var address: String? = null

Best Practices

  1. Prefer non-nullable types whenever possible.
  2. Use nullable types only when null is a valid state.

Safe Call Operator (?.)

The safe call operator allows you to safely access properties or methods on nullable objects. If the value is null, the expression returns null instead of throwing an exception.

Example


val city: String? = null
println(city?.length)

Chaining Safe Calls


val length = city?.uppercase()?.length

Best Practices

  1. Use safe calls to avoid NullPointerException.
  2. Combine with the Elvis operator for default values.

Elvis Operator (?:)

The Elvis operator provides a default value when a nullable expression evaluates to null.

Example


val name: String? = null
val length = name?.length ?: 0
println(length)

Best Practices

  1. Use Elvis operator to handle null values gracefully.
  2. Keep fallback values meaningful.

Non-Null Assertion Operator (!!)

The non-null assertion operator forces a nullable value to be treated as non-null. If the value is null, it throws a NullPointerException.

Example


val email: String? = null
println(email!!.length)

Best Practices

  1. Avoid using !! in production code.
  2. Use it only when you are absolutely sure the value is not null.

Scope Functions: let, run, also, apply

Scope functions execute a block of code within the context of an object and are commonly used for null safety and object configuration.

let

Executes code only if the object is not null and returns the last expression.


val userName: String? = "Muni"

userName?.let {
println("User name length: ${it.length}")
}

Best Practice:

  1. Use let for null checks and short transformations.

run

Executes code on an object and returns the result of the block.


val result = userName?.run {
length
}

Best Practice:

  1. Use run when you need to compute a result from an object.

also

Executes code and returns the original object.


val number = 10.also {
println("Value is $it")
}

Best Practice:

  1. Use also for logging and side effects.

apply

Executes code on an object and returns the object itself.


val person = Person().apply {
name = "Muni"
age = 35
}

Best Practice:

  1. Use apply for object initialization.

Summary

This chapter explained Kotlin’s null safety system, including nullable types, safe call and Elvis operators, non-null assertion, and scope functions. Proper use of these features helps prevent runtime crashes and ensures cleaner, safer, and more maintainable Kotlin code.