kotlin 创建KClass的新示例

zz2j4svz  于 2023-04-21  发布在  Kotlin
关注(0)|答案(5)|浏览(183)

我有一个Kotlin类,它的主(也是唯一的)构造函数是空的。
我有一个关于这个类的参考:

val kClass: KClass<MyClass> = MyClass::class

如何使用反射创建此类的示例?
在Java中,我会执行myClass.newInstance(),但在Kotlin中,我似乎需要先找到构造函数:

kClass.constructors.first().call()

我在some bug reports中看到提到了primaryConstructor,但它没有显示在我的IDE中。

6jjcrrmo

6jjcrrmo1#

在这种情况下,Java反射可能就足够了:你可以使用MyClass::class.java并创建一个新的示例,就像你使用Java反射一样(见@IngoKegel的回答)。
但是如果有多个构造函数,并且您确实需要获取主构造函数(而不是默认的无参数构造函数),请使用KClass<T>primaryConstructor扩展函数。它是Kotlin reflection的一部分,kotlin-stdlib中没有提供。
要使用它,您必须添加kotlin-reflect作为依赖项,例如Gradle项目中的a:

dependencies {
     compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"    
}

假设有ext.kotlin_version,否则用您使用的版本替换$kotlin_version
然后你可以使用primaryConstructor,例如:

fun <T : Any> construct(kClass: KClass<T>): T? {
    val ctor = kClass.primaryConstructor
    return if (ctor != null && ctor.parameters.isEmpty())
        ctor.call() else
        null
}
1wnzp6jl

1wnzp6jl2#

您可以使用Java类创建新示例:

MyClass::class.java.newInstance()
bqjvbblv

bqjvbblv3#

对于那些现在检查这个问题的人,从Kotlin1.1开始,KClass上也有createInstance()扩展方法
与可接受的答案非常相似,此函数仅在类具有空构造函数或具有所有默认参数的构造函数的情况下才起作用。
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect.full/create-instance.html

scyqe7ek

scyqe7ek4#

扩展Alexeys Answer,以包含带参数的主构造函数调用:

/* Example class with no-args constructor */
class MyClass

/* Example class requiring parameters */
class MyClassWithParams(parameter1: String, parameter2: MyClass)

val myKClass: KClass<MyClass> = MyClass::class
val myKClassWithParameters: KClass<MyClassWithParams> = MyClassWithParams::class

/* We can create an object by calling createInstance when no constructor parameters are required as explained in other answers. */
val myObject: MyClass = myKClass.createInstance()

/* To create an object with parameters, we need to get the constructor first, and call it with the parameters instead, similarly to how we would do in Java. */
val myObjectWithParameters: MyClassWithParams? = 
myKClassWithParameters.primaryConstructor?.call(
    "StringParameter", myObject
)
huwehgph

huwehgph5#

我喜欢hotkey的答案,但我无法让他的primaryConstructor代码示例工作。我确实让以下代码工作:

fun <T : Any> construct(kClass: KClass<T>): T? {
      val constructors = kClass.constructors
      for (constructor in constructors) {
           if (constructor.parameters.size == 0) return constructor.call()
      }
      return null;
    }

相关问题