创建KClass的新实例

Ric*_*ich 19 reflection kotlin

我有一个Kotlin类,其主要(也是唯一的)构造函数为空.

我引用了这个类:

val kClass: KClass<MyClass> = MyClass::class
Run Code Online (Sandbox Code Playgroud)

如何使用反射创建此类的实例?

在Java中我会这样做,myClass.newInstance()但在Kotlin中我似乎需要先找到构造函数:

kClass.constructors.first().call()
Run Code Online (Sandbox Code Playgroud)

我已经看到primaryConstructor一些错误报告中提到但它没有出现在我的IDE中.

hot*_*key 21

在您的情况下,Java反射可能就足够了:您可以像使用Java反射一样使用MyClass::class.java和创建新实例(请参阅@IngoKegel的回答).

但是如果有多个构造函数并且您确实需要获取主要构造函数(而不是默认的非参数构造primaryConstructor函数),请使用a的扩展函数KClass<T>.它是Kotlin反射的一部分,不在其中kotlin-stdlib.

要使用它,您必须添加kotlin-reflect为依赖项,例如在Gradle项目中:

dependencies {
     compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"    
}
Run Code Online (Sandbox Code Playgroud)

假设有 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
}
Run Code Online (Sandbox Code Playgroud)

  • 如果构造函数需要参数,上面的方法就没用了 (2认同)
  • 如果构造函数需要参数,推荐的方法是什么? (2认同)

Ing*_*gel 17

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

MyClass::class.java.newInstance()
Run Code Online (Sandbox Code Playgroud)

  • 真的很有趣,Kotlin没有类似的简单惯用方式 (2认同)
  • 顺便说一句,因为Java 9带有绕过检查异常的参数,所以不赞成使用Class.newInstance()。 (2认同)

Ale*_*hin 9

对于那些现在检查这个问题的人,从 Kotlin 1.1 开始,还有createInstance()扩展方法KClass

与接受的答案非常相似,此函数仅在类具有带有所有默认参数的空构造函数或构造函数的情况下才起作用。

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect.full/create-instance.html

  • 被低估的答案。多谢。 (3认同)