Kotlin 注释不在 fieldDecleration 中或已编译 java
Kotlin annotation not in fieldDecleration or compiled java
对于我在 Kotlin 中的数据对象,我为 GSON 添加了一个自定义注释以具有排除规则。
过去它运行得很好,现在它没有出现在我的 class 反射中(this.javaClass.declaredFields[3].annotations
是 null
),也没有出现在编译的 java 输出。
我尝试了不同的方法,比如升级我的 kotlin 版本、添加 kotlin-kapt、使用不同的 @Retention
类型、重新启动我的计算机(你永远不知道)并查看了其他注释。那些其他注释(例如对于 Hibernate a @OneToOne
)显示没有问题。
注解定义:
@Retention(AnnotationRetention.RUNTIME)
@Repeatable
@Target(
AnnotationTarget.FIELD,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.PROPERTY,
AnnotationTarget.VALUE_PARAMETER
)
annotation class ExcludeFromJSON
在数据中的使用 class:
@Entity
@Table(name = "user")
class User (
var username: String = "",
var email: String = "",
@ExcludeFromJSON
private var password: String
) {}
我希望注释出现在 javaClass 反射和编译的 java 代码中。它既不。
编译密码var(无注解...):
private final var password: kotlin.String /* compiled code */`
您应该使用适当的使用站点目标来限定注释:
@field:ExcludeFromJSON
private var password: String
这将导致注释出现在由此 属性 生成的 Java 字段上。
来自 Kotlin 参考 关于 Annotation Use-site Targets:
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. [...]
[...]
The full list of supported use-site targets is:
file
;
property
(annotations with this target are not visible to Java);
field
;
get
(property getter);
set
(property setter);
receiver
(receiver parameter of an extension function or property);
param
(constructor parameter);
setparam
(property setter parameter);
delegate
(the field storing the delegate instance for a delegated property).
[...]
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
.
要摆脱的三件重要事情是:
- Kotlin 中的注释在最终应用位置方面存在一定程度的歧义1。例如,将您的注释放在您所做的位置意味着该注释可以应用于至少 五个 个不同位置之一:属性、字段、getter、setter, setter 参数.
- 应用于 Kotlin 属性 的注释在 Java 端不可见。
- Kotlin 上的注释 属性,没有使用站点目标,如果它不适用于 Kotlin 属性,则只会应用于支持字段 属性。
您的注释在其 @Target
注释中同时包含 AnnotationTarget.FIELD
和 AnnotationTarget.PROPERTY
。由于您没有指定使用站点目标,因此 属性 优先——这意味着注释对 Java.
不可见
有关属性和字段的更多信息,请参阅 Kotlin 参考 的 Properties and Fields 页面。
1.这不是 技术上 模棱两可的,因为一切都已明确定义。
对于我在 Kotlin 中的数据对象,我为 GSON 添加了一个自定义注释以具有排除规则。
过去它运行得很好,现在它没有出现在我的 class 反射中(this.javaClass.declaredFields[3].annotations
是 null
),也没有出现在编译的 java 输出。
我尝试了不同的方法,比如升级我的 kotlin 版本、添加 kotlin-kapt、使用不同的 @Retention
类型、重新启动我的计算机(你永远不知道)并查看了其他注释。那些其他注释(例如对于 Hibernate a @OneToOne
)显示没有问题。
注解定义:
@Retention(AnnotationRetention.RUNTIME)
@Repeatable
@Target(
AnnotationTarget.FIELD,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.PROPERTY,
AnnotationTarget.VALUE_PARAMETER
)
annotation class ExcludeFromJSON
在数据中的使用 class:
@Entity
@Table(name = "user")
class User (
var username: String = "",
var email: String = "",
@ExcludeFromJSON
private var password: String
) {}
我希望注释出现在 javaClass 反射和编译的 java 代码中。它既不。
编译密码var(无注解...):
private final var password: kotlin.String /* compiled code */`
您应该使用适当的使用站点目标来限定注释:
@field:ExcludeFromJSON
private var password: String
这将导致注释出现在由此 属性 生成的 Java 字段上。
来自 Kotlin 参考 关于 Annotation Use-site Targets:
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. [...]
[...]
The full list of supported use-site targets is:
file
;property
(annotations with this target are not visible to Java);field
;get
(property getter);set
(property setter);receiver
(receiver parameter of an extension function or property);param
(constructor parameter);setparam
(property setter parameter);delegate
(the field storing the delegate instance for a delegated property).[...]
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
.
要摆脱的三件重要事情是:
- Kotlin 中的注释在最终应用位置方面存在一定程度的歧义1。例如,将您的注释放在您所做的位置意味着该注释可以应用于至少 五个 个不同位置之一:属性、字段、getter、setter, setter 参数.
- 应用于 Kotlin 属性 的注释在 Java 端不可见。
- Kotlin 上的注释 属性,没有使用站点目标,如果它不适用于 Kotlin 属性,则只会应用于支持字段 属性。
您的注释在其 @Target
注释中同时包含 AnnotationTarget.FIELD
和 AnnotationTarget.PROPERTY
。由于您没有指定使用站点目标,因此 属性 优先——这意味着注释对 Java.
有关属性和字段的更多信息,请参阅 Kotlin 参考 的 Properties and Fields 页面。
1.这不是 技术上 模棱两可的,因为一切都已明确定义。