The as operator in Kotlin is used for explicit type casting. There are two variants: as and as?. One throws an exception, the other is safer. This tool is important for working with polymorphism, as well as data migration and interaction with external APIs.
In Java, type casting uses the cast operator (TargetType)obj, which throws a ClassCastException on error. Kotlin developed this concept by adding a safe cast (as?), which allows for more convenient and explicit management of nullability and runtime errors.
Hard type casting in a large project is dangerous: if the type does not match, the program crashes (ClassCastException). It is important to minimize such behavior without silent errors or NPE. It is crucial to clearly separate situations where an error should be handled and when it's appropriate to simply return null.
Kotlin provides two operators:
as: strict type casting, throws ClassCastException if types do not match.as?: safe casting — returns null if casting is not possible.val x: Any = "Hello, Kotlin!" val s1: String = x as String // Ok, x is a String val s2: String? = x as? String // Ok, x is a String val n: Int? = x as? Int // n = null, safe cast
as throws ClassCastException on error.as? returns null, minimizing crash errors.Does 'as' always check the type at runtime?
Yes, if the cast occurs with incompatible types, a ClassCastException will occur. However, for some implicit conversions, such as between Int and Float, such casting does not happen — idiomatic conversion in Kotlin is done through methods (toInt, toFloat).
Can 'as' be used with a nullable type to a non-null type?
Yes, but be careful: if the value is null, an exception will be thrown. Any cast from a nullable type to a non-nullable type without checks can lead to a runtime error.
val x: String? = null val y: String = x as String // will throw ClassCastException!
What is the difference between 'is' and 'as'?
'is' is a type-checking operator. It returns true/false and does not cast. 'as' does perform casting, and if it’s not possible, it throws an exception (or returns null when using 'as?'). They are often used together for safe casting:
if (x is String) { val s: String = x // smart cast }
as without type checking that leads to ClassCastException.In the data parsing module, all objects are parsed using as, for example, obj as Double. If the data is incorrect — the application crashes with ClassCastException.
Pros:
Cons:
Using smart-cast (via is) or safe cast (as?):
val price = (obj as? Double) ?: 0.0
Pros:
Cons: