Reading — step 1 of 6
Learn
~1 min readNull Safety in Practice
Kotlin's type system tracks nullability. String cannot be null; String? can be.
Operators for working with nullables:
val s: String? = maybeName()
// Safe call — returns null if receiver is null
val len: Int? = s?.length
// Elvis — provide default
val len: Int = s?.length ?: 0
val len: Int = s?.length ?: throw IllegalStateException("no name")
// Not-null assertion (use sparingly — throws NPE on null)
val len: Int = s!!.length
// Safe cast
val x: String? = obj as? String
Smart casts — once you check, the type narrows:
fun describe(x: Any?): String {
if (x == null) return "nothing"
if (x is String) return "string of length ${x.length}" // x is String here
return "other"
}
let for null-safe transforms:
// Run block only if non-null
name?.let { processName(it) }
// Transform with null propagation
val upper: String? = name?.let { it.uppercase() }
requireNotNull / checkNotNull for asserting at API boundaries:
fun processUser(user: User?) {
val u = requireNotNull(user) { "user must not be null" }
// u is now non-null
}
The Default Map.getValue throws on missing keys — useful when your type system can guarantee presence.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…