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

标签 java hibernate kotlin annotations

对于我在 Kotlin 中的数据对象,我为 GSON 添加了一个自定义注释以具有排除规则。

在过去,这工作得很好,现在它没有出现在我的类反射中( this.javaClass.declaredFields[3].annotationsnull ),也没有出现在编译的 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 */`

最佳答案

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

@field:ExcludeFromJSON
private var password: String

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

来自关于 Annotation Use-site Targets 的 Kotlin 引用:

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 属性时才会应用于支持字段。

  • 您的注释同时具有 AnnotationTarget.FIELDAnnotationTarget.PROPERTY在其 @Target注解。由于您未指定使用站点目标,因此该属性优先——这意味着该批注对 Java 不可见。

    有关属性和字段的更多信息,请参阅 Properties and Fields Kotlin 引用的页面。

    1. 这在技术上并不含糊,因为一切都有明确的定义。

    关于java - Kotlin 注释不在 fieldDecleration 或编译的 java 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57582135/

    相关文章:

    java - libGDX 用线连接两个 Actor

    java - 使用 Hibernate 更新查询性能

    hibernate - 尽管没有关联,但调用.list()时,SQL每行运行一次

    Android AlarmManager.setExactAndAllowWhileIdle() 警报在工作一段时间后未触发

    android - 使用Kotlin从另一个列表中提取的字符串创建列表

    java - 类型转换没有关系的对象

    java - Java的三元/条件运算符可以(?:) be used to call methods instead of assigning values?

    java - 没有缓存的 EclipseLink QueryException

    java - 使用 hibernate 同步 2 个数据库 - 使用 save()、update() 还是 saveOrUpdate()?

    java - 如何在Android中获得一个月的日子