DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Kotlin Null Safety Complete Guide: ?. ?: !! let Explained

Kotlin Null Safety Complete Guide: ?. ?: !! let Explained

Kotlin's null safety is its killer feature. Master nullable types, safe calls, and null-coalescing in this complete guide.

Nullable Types

Kotlin distinguishes nullable and non-nullable at the type level:

val name: String = "Alice"        // Non-null: always has value
val age: Int? = null              // Nullable: can be null
Enter fullscreen mode Exit fullscreen mode

Safe Call Operator ?.

Call a method/property only if the value is non-null:

val text: String? = "Hello"
val length = text?.length         // 5 (or null if text is null)

data class User(val profile: Profile?)
val user: User? = User(null)
val bio = user?.profile?.bio      // null (safe chain)
Enter fullscreen mode Exit fullscreen mode

Elvis Operator ?:

Provide a default value when the left side is null:

val name: String? = null
val displayName = name ?: "Guest"  // "Guest"

fun getName(): String? = null
val result = getName() ?: "Unknown"
Enter fullscreen mode Exit fullscreen mode

Safe Cast as?

Cast safely without throwing exceptions:

val obj: Any = "Hello"
val str = obj as? String          // "Hello"

val num: Any = 42
val str2 = num as? String         // null (not a String)
Enter fullscreen mode Exit fullscreen mode

let for Null Check + Processing

Execute a block only if the value is non-null:

val email: String? = user.email
email?.let { mail ->
    sendNotification(mail)  // Only if email != null
}

// Multiple lets
user?.profile?.let { profile ->
    println(profile.bio)
}
Enter fullscreen mode Exit fullscreen mode

Why !! is Bad

The non-null assertion operator !! throws NullPointerException if the value is null:

val text: String? = null
val length = text!!.length        // ❌ Crashes at runtime!
Enter fullscreen mode Exit fullscreen mode

Use only when 100% certain the value is non-null (rare in production).

Null Safety in Compose

@Composable
fun UserCard(user: User?) {
    user?.let { u ->
        Column {
            Text(u.name)
            Text(u.email ?: "No email")
        }
    } ?: run {
        Text("User not found")
    }
}
Enter fullscreen mode Exit fullscreen mode

Collection Null Handling

val numbers: List<Int?> = listOf(1, null, 3)
val filtered = numbers.filterNotNull()  // [1, 3]

val optional: List<String>? = null
optional?.forEach { println(it) }      // Safe: no iteration if null

val mapped = optional?.map { it.uppercase() } ?: emptyList()
Enter fullscreen mode Exit fullscreen mode

Quick Reference: Null Safety Operators

Operator Use Case Returns
?. Safe property access Value or null
?: Provide default Left or right value
as? Safe cast Value or null
!! Assert non-null Value (crashes if null)
let { } Process if non-null Block result or null
?.let { } Chain safe calls Block result or null
filterNotNull() Remove nulls from list New list

Testing Null Safety

@Test
fun testNullSafety() {
    val nullable: String? = null
    assertNull(nullable?.length)
    assertEquals("Default", nullable ?: "Default")
}
Enter fullscreen mode Exit fullscreen mode

Kotlin's null safety prevents 90% of the NullPointerException bugs that plague Java. Master these operators and write crash-free code.

8 Android App Templates → https://myougatheax.gumroad.com

Top comments (0)