获取列表类与例如:列表<Number> ::类

我有一个一般类型的Builder<T> ,它需要一个构造函数参数Class<T>所以我可以保持类型。 这是一个我在java代码中使用很多的类,所以我不想更改签名。 当我尝试使用这样的构造函数:

Builder<List<Number>>(List<Number>::class)

我得到一个错误:“只有类允许在类文字的左侧”

任何方式来解决这个问题? 我不能改变Builder的构造函数,太多的Java类依赖于它。

我理解整个类型的擦除问题,我真的只是想使编译器感到高兴。

由于泛型类型的擦除, List类对其所有泛型实例都有一个实现。 您只能获得与List<*>类型相对应的类,因此只能创建Builder<List<*>>

该构建器实例适用于构建某个列表。 再次由于类型擦除什么东西是你可以自己决定在未经检查的演员的帮助下:

 Builder(List::class.java) as Builder<List<Number>> Builder(List::class.java as Class<List<Number>>) 

另一种方法是创建内联的辅助函数:

 inline fun <reified T : Any> Builder() = Builder(T::class.java) 

并以如下方式使用它:

 Builder<List<Number>>() 

解决方案是使用与超类记号相结合的泛化泛型 。

请参考这个问题解释的方法。 Kotlin中的构造函数不支持TypeReference泛型,但是可以使用TypeReference描述的TypeReference来编写builder工厂函数,该函数将在运行时保留实际的泛型参数:

 inline <reified T: Any> fun builder(): Builder<T> { val type = object : TypeReference<T>() {}.type return Builder(type) } 

然后在Builder内部,你可以检查type是否是ParameterizedType ,如果是, type.actualTypeArguments将包含实际的泛型参数。

例如, builder<List<Number>>()将在运行时保留有关Number的信息。

这种方法的局限性是你不能使用非泛化泛型作为泛化类型参数,因为在编译时必须知道类型。