This document describes the @NonNull
type annotation, and a
checker for it.
The @NonNull
type annotation indicates that a variable should
never have a null value. The plugin issues a warning whenever a variable
with a @NonNull
type may become null. This example
shows two ways this might happen: by being assigned null directly, or by
being assigned the value of a possibly-null variable.
@NonNull Object nnobj; // never null Object obj; // might be null nnobj = null; // checker will warn that nnobj will become null nnobj = obj; // checker will warn that nnobj may become null
Parameter passing and return values are checked analogously to assignments.
Suppose that the plugin issues no warnings for a given program. Then
running that program will never yield a null pointer exception as a result
of dereferencing a variable whose type is annotated with
@NonNull
. This guarantee enables a programmer to
prevent errors from occurring when his program is run.
In addition to the caveats for any checker, there are two additional caveats:
assert x !=
null; ... x.f ...
. If the JVM
is run with assertions disabled, then a null pointer exception could
occur. (Thus, writing an assertion is a way to suppress warnings in
the NonNull checker.)
The plugin
itself is built on the checkers
framework and is implemented in the checkers.nonnull
package.
The @NonNull
annotation described in this document is similar,
but not identical, to the
@NotNull
annotation of IntelliJ IDEA, the
@NonNull
annotation of FindBugs,
the non_null
modifier of JML,
and annotations proposed by
JSR
305.
The plugin currently provides a limited implementation of flow-sensitive
analysis for @NonNull
. This permits a programmer to use
references to possibly-null objects in certain circumstances where
@NonNull
objects are expected, eliminating unnecessary casts. For
example, a programmer could write:
void parse(@NonNull String) { /* ... */ }
String s = ...;
// ...
if (s != null)
parse(s);
In the above example, because the string s
is explictly
checked, it is always safe to immediately use s
where a
@NonNull
string is expected.
Flow-sensitive analysis has been implemented for the following types of expressions:
if
/else
statements assert
statementsreturn
or thrown exception,
or call System.exit
Note: The items in the above list exclude complex null checks, i.e., not of the
form x != null
. Support for these types of checks will be
available in a future release.
If you encounter a problem with flow-sensitive analysis or any part of the
@NonNull
checker, please see “How to report
bugs” for information on reporting bugs.
To try the @NonNull
plugin on a source file that uses
the @NonNull
qualifier, use the following command (where
javac
is the JSR 308 compiler):
javac -typeprocessor checkers.nonnull.NonnullChecker examples/NonNullExample.java
Compilation should complete successfully. To show an example of the checker warning about incorrect usage of annotations (and therefore the possibility of a null pointer exception at run time), use the following command:
javac -typeprocessor checkers.nonnull.NonnullChecker examples/NonNullExampleWithWarnings.java
The compiler should issue three warnings regarding violation of the
semantics of @NonNull
in the
NonNullExampleWithWarnings.java
file.
You can also run the nonnull checker on the annotation scene library, a
larger library that has been fully annotated with @NonNull
. To
run the
nonnull checker on the annotation scene library, first download the
scene
library suite (which includes build dependencies for the scene
library as well as its source code) and extract it into your checkers
installation. The checker can then be run on the annotation scene
library with Apache Ant using the following commands:
cd $CHECKERS
ant -f scene-lib-test.xml
where $CHECKERS
is the location of the checkers
installation.
You can view the annotated source code, which contains
@NonNull
annotations, in the
checkers/scene-lib-test/src/annotations/
directory.