@Retention of Java type checker annotations

社会主义新天地 提交于 2019-12-14 01:40:38

问题


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.

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
  • 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.

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?


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.


回答1:


This is a good question.

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.

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.

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? .

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).




回答2:


Each annotation has it's purpose!

javax.validation.constraints.NotNull

This ones is defined by the bean validation specification and is used to perform non-null check at runtime, so it needs to be retained at runtime to perform, for example, a form valdiation ...

@RetentionPolicy.SOURCE => usually used for documentation @RetentionPocily.CLASS => allow to give some information to the compiler but not the JVM (for example, to perform code generation during compilation) @RetentionPolicy.RUNTIME => allow to retrieve annotation information at the JVM level (so at runtime).

Regards,

Loïc



来源:https://stackoverflow.com/questions/38975073/retention-of-java-type-checker-annotations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!