英文:
Java annotation cannot be found per reflection on a Kotlin data class
问题
给定这个 Java 注解
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonProperty
和这个 Kotlin 数据类
@JsonIgnoreProperties(ignoreUnknown = true)
data class LossDocument(@JsonProperty("id") val id: String)
我期望在这里找到注解
LossDocument::class.java.declaredFields[0].annotations
或者在这里找到
LossDocument::class.java.declaredMethods.first { it.name == "getId" }
但这两者都没有任何注解。这是一个 bug 吗?根据 [53843771][1],我的印象是这应该可以工作。我使用的是 Kotlin 1.4.0。
当我将注解明确声明为 `@field:JsonProperty("id")` 时,我可以通过 `LossDocument::class.java.declaredFields[1].annotations` 毫无问题地找到它。
[1]: https://stackoverflow.com/questions/53843771
英文:
Given this Java annotation
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonProperty
and this Kotlin data class
@JsonIgnoreProperties(ignoreUnknown = true)
data class LossDocument(@JsonProperty("id") val id: String)
I would expect to find the annotation either here
LossDocument::class.java.declaredFields[0].annotations
or here
LossDocument::class.java.declaredMethods.first { it.name == "getId" }
but both have zero annotations. Is this a bug? Per 53843771, my impression is this should work. I'm using Kotlin 1.4.0.
When I declare the annotation explicitly as @field:JsonProperty("id")
I can find it without problem using LossDocument::class.java.declaredFields[1].annotations
.
答案1
得分: 2
在对属性或主构造函数参数进行注解时,会从相应的 Kotlin 元素生成多个 Java 元素,因此在生成的 Java 字节码中存在多个可能的注解位置。
如果您未指定使用点目标(use-site target),则目标将根据所使用注解的 @Target 注解进行选择。如果存在多个适用的目标,则将使用以下列表中的第一个适用目标:
param、property、field。 -- 注解使用点目标
在您的情况下,注解被放置在构造函数参数上。
英文:
> When you're annotating a property or a primary constructor parameter, there are multiple Java elements which are generated from the corresponding Kotlin element, and therefore multiple possible locations for the annotation in the generated Java bytecode.
>If you don't specify a use-site target, the target is chosen according to the @Target annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following list is used:
param, property, field. -- Annotation Use-site Targets
In your case the annotation is placed on the constructor parameter.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论