且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Kotlin数据类字段上列出(java)批注?

更新时间:2022-12-31 15:54:42

这里的问题是我的期望(可能还有文档)没有让我为Kotlin编译器对各种类型的注释所做的准备.我的假设是,Kotlin数据类属性上的FIELD目标注释目标会将注释直接应用于Kotlin合成属性.这个假设是不正确的.

The problem here is that my expectations (and possibly the documentation) didn't prepare me for what the Kotlin compiler will do with annotations of various types. My assumption was that a FIELD target annotation target on a Kotlin data class property would apply the annotation directly to the Kotlin synthetic property. This assumption was not true.

Kotlin将对合成属性上的FIELD注释执行的操作是将FIELD注释向下推至实际的后备字段.这意味着对带注释的Kotlin属性的任何形式的反射都将根本找不到该注释. 您必须深入到Java Class对象中才能找到它.

What Kotlin will do with a FIELD annotation on a synthetic property is push the FIELD annotation down to the actual backing field for the property in the generated class file. This means that any sort of reflection on the annotated Kotlin property will not find the annotation at all. You have to reach down into the Java Class object to find it.

如果要注释Kotlin类属性,并通过KClass反射找到它,则必须使用PROPERTY类型注释,这对于Kotlin是唯一的.这样,如果您在KClass的members列表中找到该属性,它将具有该注释(但没有底层的支持字段!).

If you want to annotate a Kotlin class property, and have it found via KClass reflection, you have to use the PROPERTY type annotation, which is unique to Kotlin. With this, if you find the property in the members list of a KClass, it will have that annotation (but not the underlying backing field!).

更进一步,对于Kotlin数据类,构造函数是定义该类的属性的最重要的事情.因此,如果要在运行时通过反射创建数据类实例,则***通过其构造函数对其属性进行注释.这意味着将VALUE_PARAMETER类型的注释应用于数据类的构造函数属性,可以通过反映构造函数参数本身来发现它们.

Going further, with Kotlin data classes, the constructor is the most important thing that defines the properties for the class. So, if you want to create a data class instance via reflection at runtime, it might be best to annotate its properties via its constructor. This means applying an annotation with the VALUE_PARAMETER type to the data class constructor properties, where they can be discovered by reflection of the constructor parameters itself.

从更一般的意义上讲,由Java 定义的注释类型适用于Java Class反射,而由Kotlin 扩展的注释类型适用于KClass反射. Kotlin编译器将禁止您在Java元素上使用Kotlin特定的注释类型.这里的例外是,它将允许您将Java批注类型应用于简化"为Java本机概念的Kotlin概念(带有后备字段的属性). (FWIW,如果您将Java本机注释代码复制到Kotlin中并进行自动转换,则在这种情况下,转换可能没有意义.)

In a more general sense, the annotation types that are defined by Java only apply to Java Class reflection, while the annotation types extended by Kotlin only apply to KClass reflection. The Kotlin compiler will forbid you from using Kotlin-specific annotation types on Java elements. The exception here is that, it will allow you to apply Java annotation types to Kotlin concepts (properties with backing fields) that "boil down" to Java native concepts. (FWIW, if you copy Java native annotation code into Kotlin and have it auto-convert, the conversion may not make sense without this in mind.)

如果您最喜欢的Java库仅公开适用于Java层概念的注释,请考虑要求它们提供Kotlin扩展,以帮助您在更纯粹的Kotlin级别上使用其注释.尽管在Java代码中使用它可能很棘手.

If your favorite Java library exposes only annotations that apply to Java layer concepts, consider asking them to provide Kotlin extensions that help you work with their annotations at a more purely Kotlin level. Though this might be tricky to consume in Java code.

请有人更新文档. :-)

Someone please update the docs. :-)