In Java, ANY variable can secretly be null — and your program only finds out when it crashes with the infamous NullPointerException. Kotlin was designed to kill that bug at compile time: a plain String can never hold null. When a value might be absent, you must say so in the type with a question mark — String? is a nullable type, and the compiler refuses to let you touch it until you have dealt with the null case.
var name: String = "Kotlin"
name = null // rejected at compile time!
var nickname: String? = null // fine — the ? allows null
The assignment to name never even compiles:
error: null cannot be a value of a non-null type 'String'.
And you cannot call members on a String? directly — nickname.length gives:
error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type 'String?'.
Three ways past that error:
// 1. safe call ?. — the value, or null when absent (safe)
nickname?.length // Int? : the length, or null
// 2. Elvis ?: — the value, or your fallback when null (safe)
nickname ?: "none" // never null — always a real String
// 3. !! — "trust me, it's not null": the value, or CRASH (dangerous)
nickname!!.length // throws if nickname is null
They chain nicely too: nickname?.length ?: 0 reads "the length if there is one, otherwise 0".
The trap:
!! silences the compiler — it does NOT make the value exist. This compiles without a single complaint:
val nickname: String? = null
println(nickname!!.length) // "trust me"... but it IS null
...and dies the moment it runs:
Exception in thread "main" java.lang.NullPointerException
That is the exact crash Kotlin's type system exists to prevent — !! is you overriding the safety, which is why experienced Kotlin developers treat every !! as a code smell. The rule: reach for ?. and ?: by default, and use !! only when you can prove the value is there.
Assignment
Follow the Coding Tutorial and try all three on a present and an absent value:
- declare
val present: String? = "Kotlin"andval missing: String? = null, - print the length of each with the safe call
?.length— no crash, even formissing, - print each value with the Elvis fallback
?: "none", - print
present!!.length— safe here, becausepresentcertainly holds a value.
The exact expected output is:
present length = 6
missing length = null
present or default = Kotlin
missing or default = none
forced length = 6
Hint
Build each line with a string template, e.g. println("present length = ${present?.length}"). Note that ${missing?.length} prints the word null — the safe call returned null, and the template prints it as text.
Free plan: 30 tutor messages. PRO is unlimited.
