Java 8类型注释(JSR 308)允许类型检查器执行静态代码分析。例如,检查框架可以通过@NonNull注释检查可能的空值。
各个项目定义自己的NonNull注释,例如:
org.checkerframework.checker.nullness.qual.NonNulledu.umd.cs.findbugs.annotations.NonNulljavax.annotation.Nonnulljavax.validation.constraints.NotNulllombok.NonNullorg.eclipse.jdt.annotation.NonNull对于这样的注释,我希望@interface有@保留(RetentionPolicy.CLASS),因为在运行时通常不需要它们。最重要的是,代码对各个库没有任何运行时依赖关系。
虽然org.eclipse.jdt.annotation.NonNull遵循这种方法,但大多数其他NonNull注释(如javax.annotation.Nonnull (JSR 305)和org.checkerframework.checker.nullness.qual.NonNull本身)都有@保留(RetentionPolicy.RUNTIME)。在这些注释中,有什么特殊的原因需要RetentionPolicy.RUNTIME吗?
说明: Checker支持注释中的注释,以实现向后兼容性。然而,在Java 8中使用这些代码只是为了避免运行时依赖关系,这似乎是一种肮脏的攻击。
发布于 2016-08-16 15:09:16
这是个好问题。
为了在编译时进行静态检查,CLASS保留就足够了。注意,SOURCE保留是不够的,因为单独编译:当类型检查一个类时,编译器需要读取它使用的库上的注释,而单独编译的库只作为类文件提供给编译器。
注释设计器使用RUNTIME保留来允许工具执行运行时操作。这可以包括检查注释(如assert语句)、动态加载代码的类型检查、强制转换和instanceof操作的检查、更精确地解析反射等等。如今,这样的工具并不多,但是注释设计人员希望将来能够适应这些工具。
您注意到,使用@Retention(RetentionPolicy.CLASS)时,“代码对各自的库没有任何运行时依赖关系。”@Retention(RetentionPolicy.RUNTIME)也是如此!请参见这个堆栈溢出问题:为什么缺少注释不会导致运行时的ClassNotFoundException?。
总之,在运行时使用CLASS保留会花费微不足道的空间,使将来有更多的潜在用途,而不会引入运行时依赖关系。
在Checker中,它提供了运行时测试(如isRegex(String) )。如果您的代码使用这些方法,您的代码将依赖于Checker运行时库(它比整个Checker本身要小,并且具有更许可的许可证)。
发布于 2016-08-16 12:52:38
每个注释都有它的目的!
javax.validation.constraints.NotNull此值由bean验证规范定义,用于在运行时执行非空检查,因此需要在运行时保留它以执行例如表单验证.
@RetentionPolicy.SOURCE =>通常用于文档@RetentionPocily.CLASS =>,允许将一些信息提供给编译器,而不是JVM (例如,在编译期间执行代码生成),@RetentionPolicy.RUNTIME =>允许在JVM级别(所以在运行时)检索注释信息。
致以敬意,
罗伊克
https://stackoverflow.com/questions/38975073
复制相似问题