JSR-305 allows you to define an annotation that defines a default
annotation. For example, you can apply @ParametersAreNonnullByDefault
to a package. I tried doing this for the Google collections package,
among others. Based on that experience, I want to change how I had
defined them to work (and how FindBugs interpreted them).
Google already has there own @Nullable annotation, which was used in
the collections package, and the documentation stated that unless
marked with @Nullable, any parameter should accept only nonnull
values. After applying the @ParametersAreNonnullByDefault at the
package level, I checked to see how much additional refinement was
One main issue that came up was that lots of methods implemented or
extended methods defined in java.util, those methods accepted null
parameters, but the declarations in google collections were not
This seems to make sense. Once you've defined a method (with a set of
explicit or implicit type qualifiers), an implementation/extension of
that method in another class should only use different type qualifiers
if you explicitly specify them.
As for as JSR-305, if a method declaration could or does have a
@Override annotation, then we don't look for any default annotations
from surrounding classes or the package (you can specify a default for
parameters at the method level).
In particular, with this change, the @ParametersAreNonnullByDefault at
the package level for Google collections applies only to methods newly
defined within that package. Any implementations of methods defined in
java.util interfaces or classes inherit the implicit @Nullable
annotation from those interfaces/classes.
So, the algorithm for determining the effect type qualifier annotation
for an element is:
* Check for an explicit annotation
* If not found, look for an applicable default annotation: for each
surrounding context, look for a type qualifier
default with a matching element. For a method parameter, the
surrounding contexts are: the method
declaration, the class containing the method, any outer nested
classes (from inner most to outermost),
and then the package declaration. For methods that can or do have
@Override annotation, do not examine
the contain class(es) or package for default annotations.
* If not found, look for an inherited annotation (resolving or warning
about conflicting annotations
inherited from declarations in multiple interfaces).
Just for clarification, the only place where both default and
inherited type qualifiers _might_ apply would be for method parameters
of an overriding method. In this case, both a default specification at
the method level and an inherited type qualifier might apply, and if
both were present the default specification would always win out.
Agree. If these annotations are to be viewed as type qualifiers, the types of
the arguments and return value of superclass methods are already set, and
should be honored.