← All courses

Null Safety in Depth

🗓 May 31, 2026 ⏱ 2 min read

The billion-dollar mistake

In many languages, any object can secretly be null, and calling a method on a null object crashes the app with a NullPointerException (NPE). The inventor of null famously called it his “billion-dollar mistake”. Kotlin fixes this at the language level: by default, a variable cannot hold null, and the compiler forces you to handle the cases where it can.

Nullable vs non-null types

var a: String = "hi"
// a = null          // ❌ compile error — String can never be null

var b: String? = "hi"  // the ? makes it nullable
b = null               // ✅ allowed

That single ? changes everything: now the compiler knows b might be null and won’t let you use it carelessly.

The tools for working with nullables

?. safe call ?: default ?.let { } !! (risky)
val name: String? = getName()

// 1. Safe call — returns null instead of crashing
println(name?.length)

// 2. Elvis operator — provide a default when null
val len = name?.length ?: 0

// 3. let — run a block only if not null
name?.let { println("Hello, $it") }

// 4. Not-null assertion — throws if null (use very rarely!)
val forced = name!!.length

Smart casts

Once you check that something isn’t null, Kotlin “smart casts” it to a non-null type inside that block — no extra work needed:

fun printLength(text: String?) {
    if (text != null) {
        // here the compiler KNOWS text is not null
        println(text.length)
    }
}

A real example

data class User(val name: String, val email: String?)

fun sendEmail(user: User) {
    val address = user.email ?: run {
        println("${user.name} has no email")
        return
    }
    // from here on, address is a non-null String
    println("Sending to $address")
}

Common mistakes

  • Reaching for !! to silence the compiler — it just moves the crash to runtime. Use ?. and ?: instead.
  • Making everything nullable “just in case” — design so values are non-null whenever possible.
  • Forgetting that platform types from Java may be null — treat Java return values carefully.
Summary: Add ? only when null is truly possible, then handle it with ?., ?: and let. Avoid !!. This is what makes Kotlin apps crash far less than Java ones.