Smart casts and their limits

Kotlin language Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Predict the output

What happens when you compile this?

class Profile {
    var nickname: String? = null

    fun shout(): Int {
        if (nickname != null) {
            return nickname.length
        }
        return 0
    }
}
Options
Hint 1 of 1

Is nickname a local val or a mutable property?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A Compile error: smart cast is impossible because nickname is a mutable property

Correct. The property could change between the check and the use.

Why not the others?
  • B It compiles and returns the length. The compiler can't prove nickname is still non-null.
  • C It compiles, but throws NullPointerException at runtime. It doesn't compile at all.
  • D Compile error: nickname must be lateinit. lateinit is unrelated.

30-second answer

After a check like if (x is String) or if (x != null), the compiler treats x as the narrower type without an explicit cast. It only does this when it can prove the value can't change between the check and the use: local vals, local vars not captured by a lambda that modifies them, and val properties in the same module without custom getters. Mutable properties can't be smart-cast.

Practise saying it · 30 s. No recording, just a timer

Explain smart casts and their limits.

Say your answer out loud, then check which of these points you covered:

  • Automatic narrowing after checks
  • Only when the value can't change
  • Not on var properties
  • Copy to a local val

Deep dive

Copy the property to a local val first: val n = name; if (n != null) n.length.

?.let { } gives the same effect for nullable properties.

K2 smart-casts in more places, such as after || checks and in more loops.

Explicit casts (as) throw on failure; as? returns null.

Common mistakes

  • Using !! after a null check because the smart cast failed.
  • Expecting smart casts on var properties.
  • Casting with as where as? and a fallback would be safer.

Senior take & follow-ups

Explain the 'value can't change' rule; then the fix is obvious.

Follow-up questions

Think of your answer first, then open the hint.

  1. Why can't a var property be smart-cast?

    Show hint

    Another thread or call could change it between the check and the use.

  2. What did K2 improve?

    Show hint

    Smart casts after logical operators, in loops and for more local variables.

Suggest a fix if something here is wrong or out of date.