在 kotlin 中创建泛型类的新实例的正确方法是啥?

Posted

技术标签:

【中文标题】在 kotlin 中创建泛型类的新实例的正确方法是啥?【英文标题】:What is the proper way to create new instance of generic class in kotlin?在 kotlin 中创建泛型类的新实例的正确方法是什么? 【发布时间】:2014-11-18 10:29:55 【问题描述】:

我使用以下初始化:

val entityClass = javaClass<Class<T>>()
var entity = entityClass.newInstance().newInstance()

但这是错误的,并导致IllegalAccessExceptionjava.lang.Class.newInstance(Class.java:1208)

【问题讨论】:

【参考方案1】:

如果让 IntelliJ 添加显式类型信息,您会看到 entityClass 实际上是 Class&lt;Class&lt;String&gt;&gt; 类型。我不确定这是否是你想要的。在第 2 行中,您首先创建了一个 Class&lt;T&gt; 实例,然后创建了一个 T 实例,但无论如何这是不可能的,因为关于 T 的通用信息在运行时会丢失。除此之外,您不能直接实例化类对象。

解决方案

一种可能的解决方案是将Class&lt;T&gt; 类型的参数添加到您的函数或类中,并使用它来实例化这样的对象。

fun <T> foo(entityClass: Class<T>) 
    var entity: T = entityClass.newInstance()


fun test() 
    foo(Object::class.java)

但实际上有一个更优雅的解决方案,无需使用反射。定义方法类型() -&gt; T 的参数并使用构造函数引用。 Here's my related question 关于构造函数引用,代码如下:

fun <T> foo2(factory: () -> T) 
    var entity: T = factory()


fun test() 
    foo2(::Object)

【讨论】:

嗨,如果 entityClass 是接口呢? 有没有办法在泛型类型上设置“不是接口”的界限? C# 具有类似行为的 new 关键字,表示“T 必须是可构造的”。 我猜你可以省略 entityClass 通过使函数与 reified 内联。 foo函数中创建的Object如何添加属性?【参考方案2】:

感谢Kirill Rakhman 我写了一个类似的答案(针对 android 适配器)。这里的区别在于类的参数。

private fun <T> createItem(
    viewGroup: ViewGroup,
    layoutRes: Int,
    method: (View) -> T
): T 
    val view = LayoutInflater.from(viewGroup.context).inflate(layoutRes, viewGroup, false)
    return method(view) // Creates T(view).

那就这样用吧:

override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): AbstractViewHolder 
    return when (viewType) 
        LOADER -> createItem(viewGroup, R.layout.row_loader, ::LoaderViewHolder)
        DATE -> createItem(viewGroup, R.layout.row_date, ::DateViewHolder)
        else -> throw IllegalStateException("Wrong class")
    

这里的LoaderViewHolderDateViewHolderAbstractViewHolder 的后代。

【讨论】:

以上是关于在 kotlin 中创建泛型类的新实例的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

通过未经检查的类型转换在 Java 中创建泛型数组

我无法在 Java 中创建泛型数组类型的原因是啥?

如何在颤振/飞镖中创建泛型类型的对象?

如何在打字稿的泛型类中创建类型为“T”的新对象?

Kotlin 泛型

Kotlin 五 泛型 枚举