这是我的情况的最小示例:
class Foo<T>(val list: List<Any>) {
init {
list.filterIsInstance<T>().forEach { ... } // error
}
}
自然,这不会编译:
Cannot use 'T' as reified type parameter. Use a class instead.
这种情况的惯用解决方案是什么?听起来好像编译器建议使用
KClass<T>
作为构造函数参数,但是这种用法是什么样的?
最佳答案
这里有多个问题。首先,您指定了一个错误,因为您的类T
的类型参数Foo
没有被验证。因此,您需要在声明type参数的位置使用关键字 reified
。但是然后,您将需要一个 inline
函数才能做到这一点(由于Kotlin应该支持的JVM限制)。问题是,您不能使构造函数在Kotlin中成为 inline
。
您可以根据需要找到的最接近的是:
class Foo<T>(val list: List<T>) {
init {
list.forEach { println(it) }
}
companion object {
inline fun <reified T> create(list: List<Any>): Foo<T> {
return Foo(list.filterIsInstance<T>())
}
}
}
上面的假设您只需要从列表中获取属于某个类实例的所有元素,并且仅使用
Foo
类中的那些元素即可。更新:即使您希望对
Foo
本身的实例上的类型参数进行整形,但这在Kotlin中也是不可能的(如上所述,由于JVM的限制)。因此,您需要确保创建时传递的类型相同?精细。然后,除了指定其他参数外,没有其他方法:
class Foo<T>(val list: List<Any>, `class`: Class<T>) {
init {
list.filter { `class`.isInstance(it) }.forEach { println(it) }
}
}
您没有指定要对获得的列表进行处理,以及为什么需要严格相同的类型,但是我个人不会为此而烦恼,而是使用了第一个变体。
关于generics - 在构造函数中使用模板类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60554185/