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
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)
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"
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)
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)
}
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!
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")
}
}
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()
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")
}
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)