Industrial Training




Kotlin Smart Cast


We have seen in previous tutorial Kotlin Nullable Types and Non-Nullable Types how nullable type is declared. To use this nullable types we have an option to use smart casts. Smart cast is a feature in which Kotlin compiler tracks conditions inside if expression. If compiler founds a variable is not null of type nullable then the compiler will allow to access the variable.


For example:


When we try to access a nullable type of String without safe cast it will generate a compile error.


var string: String? = "Hello!"  
    print(string.length) // Compile error  
var string: String? = "Hello!"  
    print(string.length) // Compile error  

To solve the above expression we use a safe cast as:


fun main(args: Array< String>){  
var string: String? = "Hello!"  
    if(string != null) { // smart cast  
print(string.length) // It works now!  
    }  
}  
fun main(args: Array< String>){  
var string: String? = "Hello!"  
    if(string != null) { // smart cast  
print(string.length) // It works now!  
    }  
}  			  

Output:
6

While using is or !is for checking the variable, the compiler tracks this information and internally cast the variable to target type. This is done inside the scope if is or !is returns true.


Use of is for smart cast


fun main(args: Array< String>){  
val obj: Any = "The variable obj is automatically cast to a String in this scope"  
    if(obj is String) {  
                // No Explicit Casting needed.  
println("String length is ${obj.length}")  
    }  
}  
fun main(args: Array< String>){  
val obj: Any = "The variable obj is automatically cast to a String in this scope"  
    if(obj is String) {  
                // No Explicit Casting needed.  
println("String length is ${obj.length}")  
    }  
}  			  

Output:
String length is 64

Use of !is for smart cast


fun main(args: Array< String>){  
val obj: Any = "The variable obj is automatically cast to a String in this scope"  
    if(obj !is String) {  
println("obj is not string")  
  
    } else  
    // No Explicit Casting needed.  
println("String length is ${obj.length}")  
}  
fun main(args: Array< String>){  
val obj: Any = "The variable obj is automatically cast to a String in this scope"  
    if(obj !is String) {  
println("obj is not string")  
  
    } else  
    // No Explicit Casting needed.  
println("String length is ${obj.length}")  
}  			  

Output:
String length is 64

Smart cast work according to the following conditions:


  • A val variable always aspect for local properties.
  • If a val property is private or internal the check is performed in the same module where the property is declared.
  • If the local var variable is not modified between the check and the usage, is not captured in a lambda that modifies it.


Hi I am Pluto.