【发布时间】:2019-02-24 12:34:37
【问题描述】:
我需要在运行时在 Kotlin 中动态加载类。我想检查他们是否实现了我的界面,如果是这样,全是绿色的。不幸的是,Kotlin 的“智能转换”让我失望了:
var className = "some.class.Name"
val unsafeClass = Class.forName(className).kotlin
require(unsafeClass.isSubclassOf(MyInterface::class)) {
"Class '$className' is not a MyInterface"
}
val safeClass = unsafeClass as KClass<MyInterface>
^^^^^^^^^^^^^^^^^^^^^^
Unchecked cast: KClass<out Any!> to KClass<MyInterface>
我清楚地检查了该类是否实现了给定的接口。我可以改写这段代码以避免警告吗?
我尝试使用 is KClass<MyInterface> 进行测试,但出现类型擦除错误(很明显,因为泛型类型信息在运行时消失了。)
编辑:澄清一下,我的应用程序需要在启动时读取类名"some.class.Name",在配置期间;加载这些类;检查它们是否满足接口;并为以后存储 Class 或 KClass 引用。在运行时,它将使用这些引用来创建对象,使用 cls.createInstance() 等。
我的问题:有什么方法可以做到不收到不安全的演员表警告?
当我将KClass<*> 转换为KClass<MyInterface> 时,我可以在配置时收到警告(即使我将required 类作为子类),但后来我没有收到任何警告,因为@ KClass<MyInterface> 类引用上的 987654328@ 返回经过类型检查的 MyInterface 实例。
或者,我可以将引用存储为KClass<*>,而不会在配置时发出警告,但是我会在创建实例的地方收到警告,因为我需要不安全地强制转换Object 实例到MyInterface。
有没有可以让编译器满意的解决方案?
【问题讨论】:
标签: reflection kotlin casting type-erasure