fun <T> cast(from: Any): T? = from as? T
val x = cast<String>(42) // java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Is it expected behaviour? I thought as? operator should suppress exception and return null.
The question mark is usually used in Kotlin for nullability. The “as?” also allows the cast to return null when the left-hand side is null. See the documentation:
It is written in docs : To avoid an exception being thrown, one can use a safe cast operator as? that returns null on failure.
I thought that “failure” means not only case when left-side is null, for example this works well:
Unless parameter T is reified, it’s treated as Any, so basically you wrote the following function: fun cast(from: Any): Any? = from as? Any. Obviously it works for anything and compiler adds a different check at call site which throws exception. Basically that’s limitation of type erasure inherited from JVM. In Java you would pass Class<T> instance, in Kotlin you can do the same or use reified modifier which will do the same under the hood,
The cast which throws the ClassCastException in your example is not the as? operator, it’s a cast inserted by the compiler where you assign the return value of a generic method (which is actually Any because of type erasure) to the variable of a specific type.
If I understand you correctly, you tell that ClassCastException raised after the as? operator.
But at that time result should already be null.
Why ClassCastException message tells : java.lang.Integer cannot be cast to java.lang.String ?