如何创建泛型类型的实例?

时间:2017-08-20 19:23:46

标签: android generics kotlin

我知道之前已经问过这个问题,但我还没有解决它。

我正在尝试通过泛型类型创建类的实例。

我试过这个:

Class<VH>::getConstructor.call(parameter).newInstance()

但是,我收到此错误:I get this error for this method: Callable expects 2 arguments, but 1 were provided.

我也尝试过这种方法:

inline fun <reified VH> create(): VH {
         return  VH::class.java.newInstance()
     }

但是,我无法调用它,因为我不能将泛型类型用作具体类型。

这种方法也不起作用:

fun <VH> generateClass(type: Class<VH>): VH {
        return type.newInstance()
     }

正如我所说的那样:generateClass<VH>(Class<VH>::class.java)我收到此错误:Only classes are allowed on the left handside of a class literal

我的问题简而言之:如何从泛型类型创建类的实例?

提前致谢

2 个答案:

答案 0 :(得分:0)

你做不到。除非通用类型被修改,否则它将在运行时消失,使您无法创建实例。

您的具体化函数create()的示例有效,但必须在编译期间解析一个具体类型,因此无法将标准泛型类型作为一个具体类型输入。

具体化的“类生成”示例:

inline fun <reified VH : Any> generateClass(): RecyclerView.Adapter {
    return object : RecyclerView.Adapter<VH>() {
        override fun onBindViewHolder(VH holder, int position) {
            // Do implementation...
        }
        ...
    }
}

答案 1 :(得分:0)

答案是使用反射和改进的泛型类型。

首先,确保以VH为参数的方法是内联函数。一旦你有一个通用类型的具体版本,你就可以得到它的类名。

获得类名后,可以使用反射对其进行实例化。

以下是您获得课程名称的方式:

inline fun <reified VH: CustomClass> myMethod()  {

     //Make sure you use the qualifiedName otherwise the reflective call won't find the class
     val className VH::class.qualifiedName!!
 }

以下是实例化课程的方法:

Class.forName(className).newInstance(constructorData) as VH

注意:如果该类是内部类,那么除非使用$符号替换内部类名称之前的点,否则将获得classnotfoundexception。

以下是一个例子:

com.example.package.outerClass.innnerClass - 这将抛出classnotfoundexception

com.example.package.outerClass$innnerClass - 这将成功找到班级

<强>更新

您可以使用的另一种避免反射的解决方案是使用已知的通用类型构造函数。

以下是你如何得到它的构造函数:

inline fun <reified VH: CustomClass> myMethod()  {

      val customClassConstructor =  VH::class.constructors.first()
 }

这是使用其构造函数实例化经过验证的泛型类型的方法:

customClassConstructor.call(constructorData)