Which @NonNull Java annotation to use

2019-01-10 21:47发布

问题:

What is the best 'NonNull' annotation?

"Best" in the sense of

  • Standard way e.g. future proofness (e.g. support by standard jdk etc.)
  • Support of IDE's (shows up in java doc to indicate the usage for developers)
  • Support by static analysis tools like findbugs
  • Support for runtime analysis

Here's how the world currently look like - any further insight is appreciated:

  • javax.validation.constraints.NotNull (Docs)
    + javax package thus seems futureproof
    - Part of JEE not JSE. In JSE need to import additional libs.
    - Not supported by static analysis tools (runtime validation only)

  • edu.umd.cs.findbugs.annotations.NonNull (docs)
    - external library and not an javax package
    - deprecated since findbugs version 3.X
    + used for static analysis (by findbugs and therefore Sonar)

  • javax.annotation.Nonnull (docs)
    + used for static analysis (in findbugs)
    - JSR-305 is dormant/dead/unknown as on the fb mailing list indicated. The author Bill Pugh, even if directly asked, hasn't commented the state in years...

  • org.eclipse.jdt.annotation_2.0.0 (docs, interesting presentation)
    + used for static analysis (in eclipse not in findbugs though)
    - proprietary to eclipse (didn't try to use them standalone)

  • org.jetbrains.annotations.NotNull (docs)
    + used for static analysis (in intelliJ not in findbugs though)
    - proprietary to IntelliJ (but also publicly available as a jar)

  • lombok.NonNull(docs)
    + used to control code generation
    - proprietary annotation

  • android.support.annotation.NonNull (docs)
    + static analysis in android studio
    - android specific proprietary annotation

  • org.checkerframework.checker.nullness.qual.NonNull (docs)
    + JSR308 implementation which is part of Java8 (which did introduce the ability to write annotations in different parts of your code, but did not introduce new annotations)
    + used for static code (not findbugs though) and runtime analysis
    - external lib however seems to be endorsed by the java folks

Currently I would tend to the Checker Framework but I am looking forward for other views...

[disclaimer] I know the question has been asked here however was not answered (or the answer was wrong/incomplete/outdated) [/disclaimer]

回答1:

There is no standard @NonNull annotation. Creating such an annotation was the goal of JSR 305, which has been abandoned for a long time. There will not be a standard @NonNull annotation until JSR 305 is reconstituted. Oracle has no current plans to do so. (JEE annotations are outside the scope of JSR 305.)

For futureproofing, the most important factor to consider is whether the annotation is a type annotation or a declaration annotation. Because @NonNull states a property of the variable's value rather than of the variable itself, it should be a type annotation. Being a type annotation also lets the annotation be written on more locations, as in List<@NonNull String>.

You can determine whether an annotation is a type annotation by looking at the @Target meta-annotation on the annotation's definition. As of this writing, it seems that only the Checker Framework and Eclipse versions are type annotations, so I would choose them over the ones that are declaration annotations. Note that the developers of any of the other annotations could update them to be type annotations as well; I don't know of their plans.

The only downside is that using a type annotation requires use of a Java 8 compiler. The Checker Framework has mechanisms for letting code containing its annotations be compiled by a Java 7 compiler.