@保留Java类型检查器注释 [英] @Retention of Java type checker annotations
问题描述
Java 8类型注释(JSR 308)允许类型检查器执行静态代码分析.例如,检查器框架可以通过@NonNull
批注检查可能的空度.
The Java 8 type annotations (JSR 308) allow type checkers to perform static code analysis. For example, The Checker Framework can check for possible nullness via @NonNull
annotations.
各种项目定义了自己的 NonNull 注释,例如:
Various projects define their own NonNull annotations, for example:
-
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
- 等(请参见《检查器框架手册》第3.7节)
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
- etc. (see The Checker Framework Manual, section 3.7)
For such annotations, I would expect the @interface
to have @Retention(RetentionPolicy.CLASS)
, because they are usually not needed at runtime. Most importantly, the code does not have any runtime dependencies on the respective library.
org.eclipse.jdt.annotation.NonNull
遵循此方法,大多数其他 NonNull 注释,例如javax.annotation.Nonnull
(JSR 305)和 @Retention(RetentionPolicy.RUNTIME)
.这些注释中的RetentionPolicy.RUNTIME
是否有任何特殊原因?
While org.eclipse.jdt.annotation.NonNull
follows this approach, most other NonNull annotations, like javax.annotation.Nonnull
(JSR 305) and org.checkerframework.checker.nullness.qual.NonNull
itself, have @Retention(RetentionPolicy.RUNTIME)
. Is there any particular reason for the RetentionPolicy.RUNTIME
in these annotations?
说明:Checker Framework支持注释中的注释,以实现向后兼容.但是,仅在Java 8中使用它们来避免运行时依赖似乎是一个肮脏的技巧.
Clarification: The Checker Framework supports annotations in comments for backward compatibility. However, using those in Java 8 just to avoid runtime dependencies seems like a dirty hack.
推荐答案
这是一个很好的问题.
出于编译时静态检查的目的,CLASS
保留就足够了.请注意,SOURCE
保留是不够的,因为要进行单独的编译:对类进行类型检查时,编译器需要读取其使用的库上的注释,并且单独编译的库仅可作为类文件供编译器使用.
For the purpose of static checking at compile time, CLASS
retention would be sufficient. Note that SOURCE
retention would not be sufficient, because of separate compilation: when type-checking a class, the compiler needs to read the annotations on libraries that it uses, and separately-compiled libraries are available to the compiler only as class files.
注释设计者使用RUNTIME
保留来允许工具执行运行时操作.这可能包括检查注释(如assert语句),动态加载的代码的类型检查,强制转换和instanceof
操作的检查,更精确地解决反射等问题.目前尚不存在这样的工具,但是注释设计者希望将来能够容纳它们.
The annotation designers used RUNTIME
retention to permit tools to perform run-time operations. This could include checking the annotations (like an assert statement), type-checking of dynamically-loaded code, checking of casts and instanceof
operations, resolving reflection more precisely, and more. Not many such tools exist today, but the annotation designers wanted to accommodate them in the future.
您指出,使用@Retention(RetentionPolicy.CLASS)
,代码在相应的库上没有任何运行时依赖项." @Retention(RetentionPolicy.RUNTIME)
实际上也是如此!请参阅以下堆栈溢出问题:
为什么缺少的注释不会在运行时导致ClassNotFoundException ?.
You remarked that with @Retention(RetentionPolicy.CLASS)
, "the code does not have any runtime dependencies on the respective library." This is actually true with @Retention(RetentionPolicy.RUNTIME)
, too! See this Stack Overflow question:
Why doesn't a missing annotation cause a ClassNotFoundException at runtime? .
总而言之,使用CLASS
保留时间在运行时花费的空间可忽略不计,将来有更多潜在用途,并且不会引入运行时依赖性.
In summary, using CLASS
retention costs a negligible amount of space at run time, enables more potential uses in the future, and does not introduce a run-time dependency.
In the case of the Checker Framework, it offers run-time tests such as isRegex(String)
. If your code uses such methods, your code will be dependent on the Checker Framework runtime library (which is smaller than the entire Checker Framework itself and has a more permissive license).
这篇关于@保留Java类型检查器注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!