!! Operator: When and Why to Avoid It
Understand the non-null assertion operator, its risks, and better alternatives.
!! Operator: When and Why to Avoid It is a free Kotlin Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is !!?
The non-null assertion operator !! converts a nullable type to non-null. If the value is null at runtime, it throws NullPointerException.
Basic !! Usage
x!! returns x if non-null, otherwise throws NPE.
fun main() {
val name: String? = "Kotlin"
val len: Int = name!!.length // 6
println(len)
}!! Throws on Null
If the value is actually null, you get the very exception Kotlin tries to prevent.
fun main() {
val name: String? = null
try {
println(name!!.length)
} catch (e: NullPointerException) {
println("NPE caught!")
}
}Better: Safe Call
Instead of !!, prefer ?. — graceful handling without crashes.
fun main() {
val name: String? = null
val len = name?.length
println(len) // null — no crash
}Better: Elvis Operator
Pair ?. with ?: to provide a sensible default.
fun main() {
val name: String? = null
val len = name?.length ?: 0
println(len) // 0
}Better: Smart Cast
An if (x != null) check enables a smart cast — no !! needed.
fun main() {
val name: String? = "Alice"
if (name != null) {
println(name.length) // smart-cast to String
}
}Better: requireNotNull
If the value must be present, requireNotNull(x) { "..." } throws a meaningful IllegalArgumentException.
fun process(name: String?) {
val safe = requireNotNull(name) { "name is required" }
println("processing $safe")
}
fun main() {
process("Ada")
// process(null) // throws IllegalArgumentException: name is required
}Better: checkNotNull
checkNotNull(x) behaves the same but throws IllegalStateException — use for invariants.
class Service {
private var data: String? = null
fun load() { data = "loaded" }
fun read(): String = checkNotNull(data) { "load() must be called first" }
}
fun main() {
val s = Service()
s.load()
println(s.read())
}Legitimate Uses of !!
Rare but valid: when the absence of null is a true compile-time-unprovable invariant (e.g. after a reflective call). Comment why.
fun main() {
val list = listOf(1, 2, 3)
val firstEven: Int = list.find { it % 2 == 0 }!! // safe: we know list has an even
println(firstEven)
}Chained !! — Maximum Anti-Pattern
Multiple !! in a chain is a code smell. Refactor with safe calls and guard clauses.
class A(val b: B?)
class B(val c: C?)
class C(val name: String?)
fun main() {
val a: A? = A(B(C("ok")))
// BAD: val n = a!!.b!!.c!!.name!!
val n = a?.b?.c?.name ?: "unknown"
println(n)
}Refactoring !! Away
Replace !! with a more honest API: nullable returns, requireNotNull at entry, or early return.
fun firstUpper(s: String?): String? = s?.firstOrNull()?.uppercase()
fun main() {
println(firstUpper("alice")) // A
println(firstUpper("")) // null
println(firstUpper(null)) // null
}Quick Check
What happens if you apply !! to a value that is actually null at runtime?
Recap
!! is the escape hatch that defeats Kotlin's null safety. Prefer ?., ?:, smart casts, requireNotNull, or checkNotNull. Reserve !! for documented invariants that the compiler cannot prove.
Frequently asked questions
Is the “!! Operator: When and Why to Avoid It” lesson free?
Yes — the full text of “!! Operator: When and Why to Avoid It” is free to read here on the web, and the Kotlin Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Kotlin Academy course, upgrade to CoddyKit PRO.
What will I learn in “!! Operator: When and Why to Avoid It”?
Understand the non-null assertion operator, its risks, and better alternatives. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Kotlin Academy?
No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “!! Operator: When and Why to Avoid It” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Kotlin Academy lesson?
Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Nullable Types and the ? Modifier
- Safe Call ?. and Elvis ?: in Real Code
- let, also, and run with Nullable Receivers
- !! Operator: When and Why to Avoid It