EZ

Eduzan

Learning Hub

Eduzan
Eduzan / Kotlin

Kotlin and Null Safety

Kotlin’s type system is designed to eliminate the risk of null reference errors from the code. NullPointerExceptions (NPE) often cause unexpected runtime crashes and application failures. Kotlin aims to prevent this billion-dollar mistake by handling null references at compile-time.

If you’re coming from Java or another language with null references, you’ve likely experienced NullPointerExceptions. Kotlin’s compiler throws a NullPointerException if it detects an unhandled null reference without proceeding with further execution.

Common causes of NullPointerException:

  • Explicitly calling throw NullPointerException()
  • Using the !! operator
  • Uninitialized data, such as passing an uninitialized this reference as an argument
  • Java interoperability issues, such as trying to access a member on a null reference, or using generics with incorrect nullability

Nullable and Non-Nullable Types in Kotlin

In Kotlin, references are either nullable or non-nullable. Non-nullable references cannot hold null values. If you attempt to assign null to a non-nullable reference, the compiler will raise an error.

var s1: String = "Hello"
s1 = null  // Error: compilation issue

However, to declare a variable that can hold null, we use a nullable type by appending ? to the type:

var s2: String? = "Hello Kotlin"
s2 = null  // No compilation error

If you want to access the length of a nullable string, you must use safe calls or handle the possibility of a null value:

val length = s2?.length  // Safe call, returns null if s2 is null

Example: Non-Nullable Type in Kotlin

fun main() {
    var s1: String = "Kotlin"

    println("The length of the string s1 is: ${s1.length}")
}

Output:

The length of the string s1 is: 6

In this case, assigning null to s1 would result in a compilation error.

Example: Nullable Type in Kotlin

null

Output:

var s2: String? = "Hello Kotlin"
s2 = null  // No compilation error

Here, Kotlin allows assigning null to s2 since it is a nullable type, but accessing its properties requires safe calls.

Checking for null in Conditions

You can use if-else blocks to check if a variable is null:

fun main() {
    var s: String? = "Kotlin"

    if (s != null) {
        println("String length is ${s.length}")
    } else {
        println("Null string")
    }

    s = null
    if (s != null) {
        println("String length is ${s.length}")
    } else {
        println("Null string")
    }
}

Output:

String length is 6
Null string

Safe Call Operator ?.

The ?. operator simplifies null checks. If the value before the ?. is null, the expression after ?. is not evaluated, and null is returned.

fun main() {
    var firstName: String? = "Alice"
    var lastName: String? = null

    println(firstName?.toUpperCase())  // Output: ALICE
    println(lastName?.toUpperCase())   // Output: null
}

let() Function with Safe Call

The let() function executes only when the reference is not null:

fun main() {
    var firstName: String? = "Alice"

    firstName?.let { println(it.toUpperCase()) }  // Output: ALICE
}

Example using let() with Nullable Values

fun main() {
    val stringList: List<String?> = listOf("Hello", "World", null, "Kotlin")
    val filteredList = stringList.filterNotNull()

    filteredList.forEach { println(it) }
}

Output:

Hello
World
Kotlin

The Elvis Operator ?:

The Elvis operator returns a default value when the expression on the left is null:

fun main() {
    var str: String? = null
    val length = str?.length ?: -1
    println(length)  // Output: -1
}

Example using the Elvis Operator

fun main() {
    var str: String? = "Kotlin"
    println(str?.length ?: "-1")  // Output: 6

    str = null
    println(str?.length ?: "-1")  // Output: -1
}

Not Null Assertion Operator !!

The !! operator forces Kotlin to treat a nullable type as non-null. It will throw a KotlinNullPointerException if the value is null.

fun main() {
    var str: String? = "Kotlin"
    println(str!!.length)

    str = null
    println(str!!.length)  // Throws KotlinNullPointerException
}

Output:

6
Exception in thread "main" kotlin.KotlinNullPointerException
End of lesson.