Java记录(Java records)适用于哪些注释目标?

4

我有一个用于方法或字段的注释,定义如下:

@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:注释类型对此类声明不适用"的错误提示 - 实际上这正是我所期望的。

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

1
如果你的意思是防止用户成功编译代码,那么你可以参考 lombok 中 @AllArgsConstructor 的例子(https://github.com/rzwitserloot/lombok/blob/master/test/transform/resource/messages-delombok/ConstructorsOnRecord.java.messages)来解决你的问题。具体实现细节需要在该处跟进。 - Naman
1
@Naman 谢谢,但我的库没有依赖项。对我来说很容易添加一个警告日志,并且我会记录这个。 - sproketboy
1个回答

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

description看起来有点像参数,但是对于注解定位的目的来说,并不仅仅是参数。它也可以像字段一样使用。

来自JLS(此版本已经突出显示了相对于记录更改的部分):

记录类的记录组件上的注释可能会按照8.10.3中指定的方式传播到记录类的成员和构造函数。

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

添加构造函数时出现错误的事实是一个漏洞,并且已经修复。注释的有效性应该与是否指定构造函数无关。在Java的未来版本中,您的这两个示例都将编译成功。

我想防止用户在记录上使用此[注释]

对不起,这是不可能的。


2
谢谢!我的错,我在15以下测试了。在16以上可以正常工作。没关系,我可以测试并忽略注释,并记录下这种行为。 - sproketboy
7
如果注解允许使用FIELD、PARAMETER、METHOD或RECORD_COMPONENT中的任何一个作为目标,它将传播到相应的地方。如果允许多个目标,则会传播到多个位置。如果没有允许的目标,则该注解不适用且会导致错误。 - Brian Goetz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接