Smart casting is een mechanisme waarbij de Kotlin-compiler automatisch het type "verlaagt" na controle op een bepaald type of null. Dit stelt je in staat om eigenschappen en methoden van het type waarin de casting is uitgevoerd te gebruiken, zonder expliciete conversie.
fun demo(x: Any) { if (x is String) { println(x.length) // x is automatisch omgezet naar String } }
Werkt met:
is / !is operatoren (bijvoorbeeld in if of when)if (x != null))when-expressiesWerkt niet:
val str: String? = getString() if (str != null) println(str.length) // smart cast
val something: Any get() = fetch() if (something is String) { println(something.length) // Fout: smart cast is niet mogelijk }
Kun je rekenen op smart cast voor open of var-eigenschappen van een klasse binnen methoden?
Nee! Smart cast werkt alleen met lokale variabelen en val-eigenschappen in final-klassen. Voor open (open) of var-eigenschappen is de compiler niet zeker of de waarde kan veranderen door andere threads of afgeleiden. Voor hen is handmatige casting of een lokale variabele vereist.
open class Base { open var maybeString: Any? = "abc" fun check() { if (maybeString is String) { // println(maybeString.length) // Fout: Smart cast is niet mogelijk val asString = maybeString as String println(asString.length) // Expliciete cast } } }
Verhaal
In een project werden open var-eigenschappen van datamodellen gebruikt voor schermlogica. De programmeur rekende op smart cast na controle if (model is SomeType), maar bij het compileren moest alles handmatig worden gecast, wat de leesbaarheid verminderde en code duplicatie toevoegde vanwege het onbegrip van de beperkingen van smart cast op var/open.
Verhaal
Bij het verkrijgen van gegevens via een getter (bijvoorbeeld via delegatie of validatie), werkte de smart cast voor de waarde niet. De ontwikkelaar begreep de redenen niet en besteedde enkele uren aan debuggen, totdat hij ontdekte dat de compiler geen smart cast toepast op dergelijke getters, omdat ze verschillende waarden kunnen retourneren tussen aanroepen.
Verhaal
In een project, bij de verwerking van nullable-waarden via if (obj != null), werkte smart cast binnen de tak, maar bij het paralleliseren van de code verschenen er NullPointerExceptions door verwijzingen buiten het gebied van garantie. Dit toonde onvoldoende begrip van de lokale werking van smart cast en de eigenaardigheden van multi-thread scenario's met nullable-variabelen.