How do I handle null values safely in Kotlin?

Kotlin handles null safety through its type system: a normal type like String cannot be null, while a nullable type like String? can be null.

1. Use nullable types when a value may be null

val name: String = "Alice"   // Cannot be null
val nickname: String? = null // Can be null

If a value is nullable, Kotlin will not let you access it directly without handling the null case.

val length = nickname.length // Compile error

2. Use the safe-call operator ?.

Use ?. to access a property or call a function only when the value is not null.

val name: String? = getName()

val length: Int? = name?.length

If name is null, length becomes null instead of throwing a NullPointerException.

3. Use the Elvis operator ?: for defaults

Use ?: to provide a fallback value when something is null.

val name: String? = getName()

val length: Int = name?.length ?: 0

You can also return early or throw an exception:

fun printName(name: String?) {
    val nonNullName = name ?: return
    println(nonNullName)
}
fun requireName(name: String?) {
    val nonNullName = name ?: error("Name is required")
    println(nonNullName)
}

4. Use if null checks and smart casts

After checking that a nullable value is not null, Kotlin smart-casts it to a non-null type.

fun printLength(text: String?) {
    if (text != null) {
        println(text.length)
    } else {
        println("Text is null")
    }
}

Inside the if block, text is treated as a non-null String.

5. Use let to run code only when non-null

?.let { ... } is useful when you want to execute a block only if the value exists.

val email: String? = getEmail()

email?.let {
    println("Sending email to $it")
}

You can combine it with Elvis for the null case:

email?.let {
    println("Sending email to $it")
} ?: println("No email available")

6. Avoid !! unless you truly mean “crash if null”

The not-null assertion operator !! converts a nullable value to a non-null value, but throws a NullPointerException if the value is null.

val name: String? = getName()
val length = name!!.length

Prefer safer alternatives:

val length = name?.length ?: 0

Use !! only when null would indicate a serious programmer error, and you want the program to fail immediately.

7. Prefer non-nullable function parameters when possible

If a function requires a value, declare it as non-nullable.

fun greet(name: String) {
    println("Hello, $name")
}

If null is a valid input, declare it explicitly:

fun greet(name: String?) {
    println("Hello, ${name ?: "Guest"}")
}

Quick guide

Situation Use
Access nullable value safely value?.property
Provide default if null value ?: default
Run code only if non-null value?.let { ... }
Check manually if (value != null)
Require non-null and crash if null value!!
Disallow null entirely Use non-null type, e.g. String

In general: prefer non-nullable types, use ?. and ?: for safe handling, and avoid !! unless absolutely necessary.