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

Sje*_*kie 5 java annotations hibernate kotlin

对于 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
Run Code Online (Sandbox Code Playgroud)

数据类中的用法:

@Entity
@Table(name = "user")
class User (

        var username: String = "",
        var email: String = "",

        @ExcludeFromJSON
        private var password: String
) {}
Run Code Online (Sandbox Code Playgroud)

我希望注释出现在 javaClass 反射和编译的 java 代码中。它两者都没有。

编译后的密码var(无注释...):

@Retention(AnnotationRetention.RUNTIME)
@Repeatable
@Target(
        AnnotationTarget.FIELD,
        AnnotationTarget.PROPERTY_GETTER,
        AnnotationTarget.PROPERTY_SETTER,
        AnnotationTarget.PROPERTY,
        AnnotationTarget.VALUE_PARAMETER
)
annotation class ExcludeFromJSON
Run Code Online (Sandbox Code Playgroud)

Sla*_*law 8

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

\n\n
@field:ExcludeFromJSON\nprivate var password: String\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
\n\n

来自Kotlin 参考中有关注释使用站点目标的内容

\n\n
\n

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

\n\n

[...]

\n\n

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

\n\n
    \n
  • file;
  • \n
  • property(具有此目标的注释对 Java 不可见);
  • \n
  • field;
  • \n
  • get(财产获取者);
  • \n
  • set(财产设置者);
  • \n
  • receiver(扩展函数或属性的接收者参数);
  • \n
  • param(构造函数参数);
  • \n
  • setparam(属性设置器参数);
  • \n
  • delegate(存储委托属性的委托实例的字段)。
  • \n
\n\n

[...]

\n\n

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

\n\n
    \n
  • param;
  • \n
  • property;
  • \n
  • field
  • \n
\n
\n\n

从中可以得到的三件重要的事情是:

\n\n
    \n
  1. Kotlin 中的注解对于它们的最终应用位置存在一定程度的歧义1 。例如,将注释放在您所做的位置意味着该注释可以应用于至少五个不同位置之一:属性、字段、getter、setter、setter 参数。
  2. \n
  3. 应用于 Kotlin 属性的注释在 Java 端不可见。
  4. \n
  5. 如果 Kotlin 属性上的注释没有使用站点目标,则仅当它不适用于应用于 Kotlin 属性时才会应用于支持字段。
  6. \n
\n\n

您的注释在其注释中同时包含AnnotationTarget.FIELD和。由于您没有指定使用站点目标,因此该属性优先\xe2\x80\x94,这意味着该注释对 Java 不可见。AnnotationTarget.PROPERTY@Target

\n\n

有关属性和字段的更多信息,请参阅Kotlin 参考属性和字段页面。

\n\n
\n\n

1.从技术上讲,它并不含糊,因为一切都已明确定义。

\n