Careeroza
Smart Casts
The Compiler Casts for You
After an is check, Kotlin automatically treats the variable as that type inside the checked branch - no manual cast needed. This is a smart cast. It also works after &&, ||, early return, and in when.
Example
fun lengthOf(x: Any): Int {
if (x is String) return x.length // x is String here
if (x !is List<*>) return -1 // early return
return x.size // x is List<*> here
}
fun main() {
println(lengthOf("Kotlin"))
println(lengthOf(listOf(1, 2, 3)))
println(lengthOf(42))
val v: Any = "hello"
if (v is String && v.length > 3) println(v.uppercase()) // smart cast after &&
}Output
6 3 -1 HELLO
When Smart Casts Do Not Work
A smart cast only works if the compiler can prove the value cannot change between the check and the use. It works for local vals, local vars not changed in between, and val properties in the same module without a custom getter. It does not work for var class properties (another thread could change them) or open/custom-getter properties.
Example
Fix: copy the property into a local val first.
class Screen {
var message: Any? = "Welcome back"
fun show() {
// if (message is String) println(message.length) // error: smart cast impossible
val m = message // local copy
if (m is String) println("${m.length} chars: $m")
}
}
fun main() {
Screen().show()
}Output
12 chars: Welcome back