kotlinbeginner

Null Safety — Elvis, Safe Call, and let

Master Kotlin null safety: safe calls, Elvis operator, let/also scoping, and smart casts.

kotlin
fun main() {
    // Nullable type
    val name: String? = "Alice"
    val missing: String? = null

    // Safe call operator ?.
    println(name?.length)     // 5
    println(missing?.length)  // null (no NPE)

    // Elvis operator ?:
    val len = missing?.length ?: 0
    println("Length: $len") // 0

    // Elvis with throw
    fun getUser(id: Int): String =
        findUser(id) ?: throw IllegalArgumentException("User $id not found")

    // let — execute block if non-null
    name?.let { n ->
        println("Name is $n with ${n.length} chars")
    }

    // also — side effects
    val upper = name?.also { println("Processing: $it") }
        ?.uppercase()
    println(upper) // ALICE

    // Safe casts
    val value: Any = "hello"
    val str: String? = value as? String   // "hello"
    val num: Int? = value as? Int          // null (safe)
    println("str=$str, num=$num")

    // Chained safe calls
    data class Address(val city: String?)
    data class User(val address: Address?)

    val user: User? = User(Address("NYC"))
    val city = user?.address?.city ?: "Unknown"
    println("City: $city") // NYC

    // requireNotNull / checkNotNull
    val config: String? = System.getenv("APP_CONFIG")
    // val required = requireNotNull(config) { "APP_CONFIG must be set" }

    // Smart cast after null check
    fun process(input: String?) {
        if (input != null) {
            // Smart cast: input is String here
            println(input.uppercase())
        }
        // Or with require
        input ?: return
        println(input.lowercase()) // Smart cast
    }
    process("test")
}

fun findUser(id: Int): String? = if (id == 1) "Alice" else null

Use Cases

  • Safe navigation through nullable chains
  • Default values for missing data
  • Null-safe API consumption

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.