Introduction
Type casting is the process of converting a variable data type from one to another.
Keep in mind that type casting operation is error-prone one.
This is why you learn about casting operation. If not, fatal error or exception would occur.
Any
Any
is the root of the Kotlin class, which means that every Kotlin class has Any
as a parent class.
In other terms, any Kotlin variable can have Any
as a type.
Unsafe casting
You can use as
keyword for unsafe casting
Let me show you explicit unsafe casting using as
.
val num : Any = 42
val str1 : String = num as String
println(str1)
This code would lead to following error:
Exception in thread "main" java.lang.ClassCastException:
class java.lang.Integer cannot be cast to class java.lang.String
Similarly, the as
cast operator should fail when nullable types are involved, as shown below
val num : Any? = null
val str1 : String = num as String
println(str1)
So, everytime you perform an explicit unsafe cast through the as
operator
You should consider that a ClassCastException
might be thrown.
If you want to prevent this error from crashing your application, you must handle it as follows:
val num : Any? = null
try {
val str1: String = num as String
println(str1)
} catch (e: ClassCastException) {
println("Cast failed!")
}
Safe Casting
The as?
cast operator is called safe because it returns null
when the cast can't be performed.
In other words, it's considered safe because it allows you to avoid exceptions, returning null
on failure.
as?
operator allow receiver variable should always be nullable when casting fails.
val champ : Any = "khazix"
val str1 : String = champ as? String
println(str1)
This code would lead to following error:
Kotlin: Type mismatch: inferred type is String? but String was expected
Because str1 doesn't have a nullable type. \
To make it work, all you have to do it declare str1 as String?
:
val champ : Any = "khazix"
val str1 : String? = champ as? String
println(str1)
Avoid ClassCastException
with as?
keyword
var num: Any = 42
val str1: String? = num as? String
println(str1)
This would no longer fail. it would print:
null
You can avoid ClassCastException
even though fail since 'Integer' can't be cast to 'String'.
So the try ~ catch
statement is no longer required when using as?
the safe cast operator.
You have to consider receiver variable has null
value when cast failed.
val str1: String? = num as? String
if (str1 == null) {
// Cast failed!
} else {
// Cast succeeded!
}
📝 Summary
Use
as
operator only when you can make sure the cast will be successful.
For example when casting a type to its supertype in an inheritance hierarchy.Use
as?
operator with handling null-checking code. Your application wouldn't be shut down even type casting fails.
However, required how to deal with them.