java - Kotlin noarg 插件 : Constructor only accessible by java reflection

标签 java gradle kotlin reflection

我的设置有问题,但我不知道它是什么。 来自 Kotlin compiler plugins我有以下信息。

The no-arg compiler plugin generates an additional zero-argument constructor for classes with a specific annotation.

The generated constructor is synthetic so it can’t be directly called from Java or Kotlin, but it can be called using reflection.

也就是说,我认为我可以通过 java 和 kotlin 反射访问 noarg 构造函数,但我只能通过 java 反射访问它。这是预期的行为,还是我做错了什么?

构建.gradle

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.50'
    id "org.jetbrains.kotlin.plugin.noarg" version "1.3.50"
    id 'application'
    id 'java'
}

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
    compile group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: '1.3.50'
}

noArg {
    annotation('noargdemo.Entity')
}

application {
    mainClassName = 'noargdemo.AppKt'
}
package noargdemo

import kotlin.reflect.full.createInstance

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Entity

@Entity
data class Employee(
        val firstName : String,
        val secondName : String
)

fun main(args: Array<String>) {
    val kotlinConstructors = Employee::class.constructors // size is 1
    val javaConstructors = Employee::class.java.constructors // size is 2
    val instance1 = Employee::class.java.getConstructor().newInstance() // works
    val instance2 = Employee::class.createInstance() // doesnt work
}

最佳答案

这是预期的行为,甚至在您引用的描述中也有说明:

The generated constructor is synthetic so it can’t be directly called from Java or Kotlin, but it can be called using reflection.

合成方法是编译器出于内部目的而生成的方法,无法从源代码手动调用它们,但它们对于反射是可见的。

您可以使用 Method.isSynthetic 检查方法是否是合成的: https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#isSynthetic--

关于java - Kotlin noarg 插件 : Constructor only accessible by java reflection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58993196/

相关文章:

java - 将电话号码(手机或固定电话)拆分为国家代码、区号和号码

安卓gradle : Sharing dependencies between product flavors

android - 如何在android中使用数据绑定(bind)实现Switch

java - 从 Java 中的阿拉伯 Unicode 代码点列表中检索表示形式的任何方法

java - Log.e 在拦截器中产生一些问题

gradle - 将项目资源添加到Gradle Custom插件

android - 在 Gradle 中删除带有模式的目录

kotlin - 改造查询参数添加apiKey

android - 可以将流从一个可组合传递到另一个吗?

java - 保证多边形法线的向外方向