为了账号安全,请及时绑定邮箱和手机立即绑定

Kotlin 注释不在 fieldDecleration 或已编译的 java 中

Kotlin 注释不在 fieldDecleration 或已编译的 java 中

牛魔王的故事 2023-06-14 16:44:26
对于我在 Kotlin 中的数据对象,我为 GSON 添加了一个自定义注释以具有排除规则。在过去,它工作得很好,现在它没有出现在我的类反射 ( this.javaClass.declaredFields[3].annotationsis 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在数据类中的用法:@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 */`
查看完整描述

1 回答

?
九州编程

TA贡献1785条经验 获得超4个赞

您应该使用适当的使用站点目标来限定注释:

@field:ExcludeFromJSON
private var password: String

这将导致注释出现在此属性生成的 Java 字段上。

来自Kotlin Reference regarding Annotation Use-site Targets:

当您注释属性或主要构造函数参数时,有多个 Java 元素是从相应的 Kotlin 元素生成的,因此在生成的 Java 字节码中有多个可能的注释位置。[...]

[...]

支持的使用站点目标的完整列表是:

  • file;

  • property(具有此目标的注释对 Java 不可见);

  • field;

  • get(财产获取者);

  • set(属性设置器);

  • receiver(扩展函数或属性的接收参数);

  • param(构造函数参数);

  • setparam(属性设置器参数);

  • delegate(存储委托属性的委托实例的字段)。

[...]

如果您不指定使用站点目标,则根据@Target所使用的注释的注释来选择目标。如果有多个适用目标,则使用以下列表中的第一个适用目标:

  • param;

  • property;

  • field.

要摆脱的三件重要事情是:

  1. Kotlin 中的注释在最终应用位置方面存在一定程度的歧义1 。例如,将注释放置在您所做的位置意味着可以将注释应用于至少五个不同位置之一:属性、字段、getter、setter、setter 参数。

  2. 应用于 Kotlin 属性的注解在 Java 端是不可见的。

  3. 如果 Kotlin 属性上的注解没有 use-site 目标,则仅当它不适用于 Kotlin 属性时才会应用于支持字段。

您的注释在其注释中同时包含AnnotationTarget.FIELD和。由于您没有指定 use-site 目标,因此该属性优先——这意味着注释对 Java 不可见。AnnotationTarget.PROPERTY@Target


查看完整回答
反对 回复 2023-06-14
  • 1 回答
  • 0 关注
  • 74 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信