java - @Retention Java 类型检查器注解

标签 java annotations retention checker-framework

Java 8 类型注释 (JSR 308) 允许类型检查器执行静态代码分析。例如,The Checker Framework可以通过 @NonNull 注释检查可能的nullness

各个项目定义了自己的NonNull注解,例如:

  • org.checkerframework.checker.nullness.qual.NonNull
  • edu.umd.cs.findbugs.annotations.NonNull
  • javax.annotation.Nonnull
  • javax.validation.constraints.NotNull
  • lombok.NonNull
  • org.eclipse.jdt.annotation.NonNull
  • 等(参见 The Checker Framework Manual, section 3.7)

对于这样的注释,我希望 @interface@Retention(RetentionPolicy.CLASS) ,因为在运行时通常不需要它们。最重要的是,代码对各自的库没有任何运行时依赖性。

同时 org.eclipse.jdt.annotation.NonNull大多数其他 NonNull 注释都遵循这种方法,例如 javax.annotation.Nonnull (JSR 305) 和 org.checkerframework.checker.nullness.qual.NonNull本身,有@Retention(RetentionPolicy.RUNTIME) .这些注释中的 RetentionPolicy.RUNTIME 是否有任何特殊原因?


说明:Checker Framework 支持注释中的注释以实现向后兼容性。然而,在 Java 8 中使用它们来避免运行时依赖似乎是一种肮脏的 hack。

最佳答案

这是个好问题。

为了在编译时进行静态检查,CLASS 保留就足够了。请注意,保留 SOURCE 是不够的,因为需要单独编译:在对类进行类型检查时,编译器需要读取它使用的库上的注释,并且单独编译的库可供编译器仅作为类文件。

注释设计者使用RUNTIME 保留来允许工具执行运行时操作。这可能包括检查注释(如 assert 语句)、动态加载代码的类型检查、强制转换和 instanceof 操作检查、更精确地解析反射等等。如今这样的工具并不多,但注释设计者希望将来能容纳它们。

您评论说,使用 @Retention(RetentionPolicy.CLASS),“代码对相应的库没有任何运行时依赖性。” @Retention(RetentionPolicy.RUNTIME) 实际上也是如此!看到这个堆栈溢出问题: Why doesn't a missing annotation cause a ClassNotFoundException at runtime? .

总而言之,使用 CLASS 保留在运行时占用的空间量可以忽略不计,可以在未来实现更多潜在用途,并且不会引入运行时依赖性。

对于 Checker Framework,它提供运行时测试,例如 isRegex(String) .如果您的代码使用此类方法,您的代码将依赖于 Checker Framework 运行时库(它比整个 Checker Framework 本身更小并且具有更宽松的许可)。

关于java - @Retention Java 类型检查器注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38975073/

相关文章:

java - Selenium 网格和 azure

java - 如何更改 JAXB 实现?

azure - 从表存储中删除旧的 Windows Azure 诊断数据(性能计数器等)

sql - 使用 Google Analytics 导出的数据在 BigQuery 中进行队列/保留查询

java - 文件中的句子计数器

JAVA从服务器推送到客户端

java - 在 JPanel Netbeans 上获取单击目标

java - @Before 和 @AfterReturning 组合可能吗?

asp.net-mvc - 如何对数据注释验证器进行单元测试

python - 如何从 Azure ADLS Gen 1 在 Azure 机器学习工作室中注册特定版本的增量表?