【问题标题】:Dynamic cast in KotlinKotlin 中的动态转换
【发布时间】:2020-03-15 02:57:07
【问题描述】:

我想使用KClass<Int>Any 转换为Int,有一个KClass<Int> 和一个Any,实际上是Int

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

cast(0, Int::class)

但是,我收到了这个错误。

java.lang.ClassCastException:无法将 java.lang.Integer 转换为 int

你知道除了any as Int之外的任何解决方案吗?

【问题讨论】:

  • 您需要为此使用 kotlin 反射。 Java 反射不起作用

标签: java casting kotlin


【解决方案1】:

尝试将您的代码更改为

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

说明

因为参数any 的类型是Any,所以它始终是一个引用类型并且原语将被装箱。对于第二个参数,Kotlin 反射似乎更喜欢原始类型而不是引用类型,这就是为什么Int::class.java 将默认为ìnt,而不是Integer。通过使用javaObjectType,我们强制使用盒装引用类型。

另类

您还可以使用以下函数定义:

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

// usage

cast<Int>(0)

【讨论】:

  • inline fun &lt;reified T:Any&gt; Any.cast() = this as? T怎么样
【解决方案2】:

Kirill Rakhman 的答案适用于不可为空的类型。但是如果 T 可以为空,我们就不能有 T::class。所以我建议以下处理可空类型。

inline fun <reified T> cast(any: Any?): T = any as T

用法

val l32: Number = cast(32L)
val ln1: Number? = cast(null) // works
val ln2: Number = cast(null) // fails at runtime

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多