Type checks and casts are essential in any programming language. Type checks allow developers to verify if an object belongs to a particular data type, while type casts enable programmers to convert an object from one type to another. Kotlin, being a statically-typed language, has several features that make type checks and casts easy and safe to use.
is and !is operators
The is and !is operators in Kotlin are used for type checks. They allow developers to check if an object belongs to a particular data type. The is operator returns true if an object belongs to the specified type and false if it doesn't. Conversely, the !is operator returns true if an object doesn't belong to the specified type and false if it does.
For example:
val obj: Any = "Hello, Kotlin"
if (obj is String) {
println(obj.uppercase())
} else {
println("obj is not a String")
}In the above code, we use the is operator to check if the obj variable is a String. If it is a String, we convert it to uppercase and print it. Otherwise, we print a message saying that obj is not a String. This is a good example for the is operator, but let's remember the idioms in Kotlin, one of the advantages of this programming language. One of the often used idioms in Kotlin is:
when (x) {
is Foo -> ...
is Bar -> ...
else -> ...
}Look at an example of how we can use that:
fun processInput(input: Any) {
when (input) {
is Int -> println("Input is an integer")
is String -> println("Input is a string")
is Double -> println("Input is a double")
else -> println("Unknown input")
}
}In this example, the function processInput takes an argument of type Any, which means it can accept any type of object. Within the function, we use when with is to check the type of the input object. Depending on the type, we print a message indicating what type of input it is. If the input object is not one of the expected types, we print the "Unknown input" message.
Smart casts
Kotlin also has a feature known as smart casts. Smart casts are used to simplify code when working with nullable types. When a nullable type is checked with the is operator, Kotlin automatically casts the object to a non-nullable type.
For example:
fun printLength(obj: Any) {
if (obj is String) {
println(obj.length)
}
}In the above code, we check if the obj variable is a String by using the is operator. If it is a String, we print its length. Since Kotlin automatically casts the obj variable to a non-nullable type, we don't need to use any type cast operator.
"Unsafe" cast operator
Kotlin has an unsafe cast operator, which is represented by the as keyword. The as keyword is used to cast an object to a non-nullable type. If the object cannot be cast to the specified type, the as operator throws a ClassCastException.
For example:
val obj: Any = "Hello, Kotlin"
val str: String = obj as String // Unsafe cast operator
println(str.uppercase())In the above code, we use the as operator to cast the obj variable to a String. If obj is not a String, the as operator throws a ClassCastException.
"Safe" (nullable) cast operator
Kotlin also has a safe cast operator, which is represented by the as? keyword. The as? operator is used to cast an object to a nullable type. If the object cannot be cast to the specified type, the as? operator returns null.
For example:
fun main() {
val obj: Any = 123
val str: String? = obj as? String // Safe (nullable) cast operator
if (str != null) {
println(str.uppercase())
}
}In the above code, we use the as? operator to cast the obj variable to a String. Since obj is not a String, the as? operator returns null. Therefore, the println statement doesn't print anything.
Conclusion
In conclusion, type cast and smart cast are important features in Kotlin, which allow checking and casting objects to different types. They are useful when working with objects of different types and performing operations that require a specific type. Now let's move on to practice to better remember this topic.