Search code examples
javacastingkotlin

Dynamic cast in Kotlin


I want to cast Any to Int by using KClass<Int>, having a KClass<Int> and a Any which is actually Int.

fun <T> cast(any: Any, clazz: KClass<*>): T = clazz.java.cast(any) 

cast(0, Int::class)

However, I got this error.

java.lang.ClassCastException: Cannot cast java.lang.Integer to int

Do you know any solution except any as Int?


Solution

  • Try to change your code to

    fun <T: Any> cast(any: Any, clazz: KClass<out T>): T = clazz.javaObjectType.cast(any) 
    

    Explanation

    Because the type of the parameter any is Any, it's always a reference type and primitives will be boxed. For the second parameter, it seems that Kotlin reflection will prefer primitive types to reference types, which is why Int::class.java will default to ìnt, not Integer. By using javaObjectType we force the usage of the boxed reference type.

    Alternative

    You could also use the following function definition:

    inline fun <reified T: Any> cast(any: Any): T = T::class.javaObjectType.cast(any) 
    
    // usage
    
    cast<Int>(0)