【问题标题】:What annotation targets are applicable to Java records?哪些注解目标适用于 Java 记录?
【发布时间】:2021-04-13 12:30:00
【问题描述】:

我有一个注释用于这样定义的方法或字段:

@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD})
public @interface NotColumn {
}

我想阻止用户在记录上使用它,因为在该上下文中使用此注释没有意义。似乎这样做不应该编译,因为我没有将ElementType.PARAMETER 指定为有效的@Target

以下编译正常:

public record MyRecord(String customerId,
                       String companyName,
                       @NotColumn String description
}

但是这种带有紧凑构造函数的表单无法使用“java: annotation type not applicable to this kind of declaration”进行编译——这实际上是我所期望的。

public record MyRecord(String customerId,
                       String companyName,
                       @NotColumn String description
   public MyRecord {
   }
}

【问题讨论】:

  • 如果阻止您的意思是不让用户成功编译代码,那么您可以按照@AllArgsConstructor from lombok 的示例为您的用例。实施细节需要在那里跟进。
  • @Naman 谢谢,但我的库没有依赖项。添加警告日志对我来说很容易,我会记录下来。

标签: java annotations java-record java-16


【解决方案1】:
public record MyRecord(String customerId,
                       String companyName,
                       @NotColumn String description

description 可能看起来有点像一个参数,但出于注释定位的目的,严格来说并非如此。它也可以像一个字段一样工作。

来自the JLS(此版本突出了记录发生变化的部分):

记录类的记录组件上的注释可以传播 到记录类中指定的成员和构造函数 8.10.3.

第 8.10.3 节的要点是,诸如 @NotColumn 之类的注释会传播到生成的方法、字段和参数仅当它们适用于这些目标时。否则它们将被忽略。您的注释适用于字段,因此它将传播到记录的生成的description 字段。

The fact that you get an error when adding a constructor is a bug 并且已经修复。无论您是否指定构造函数,注释的有效性都应该是相同的。在 Java 的未来版本中,您的两个示例都可以正常编译。

我想阻止用户在记录上使用这个 [注释]

这是不可能的,对不起。

【讨论】:

  • 谢谢!这对 15 岁以下的测试不利。它在 16 岁以下可以正常工作。没关系,我可以测试并忽略注释并记录该行为。
  • 如果注释允许使用任何目标 FIELD、PARAMETER、METHOD 或 RECORD_COMPONENT,则将其传播到相应的位置。如果允许多于一个,则将其传播到多个地方。如果不允许,则注释不适用并导致错误。
猜你喜欢
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
相关资源
最近更新 更多