Default annotations should not apply to overriding method declarations

488 views
Skip to first unread message

Bill Pugh

unread,
Jan 22, 2009, 11:42:25 AM1/22/09
to jsr...@googlegroups.com
I've been trying to apply JSR-305 nullness annotations at Google. That
effort has led to me two thoughts, one of which I'm fairly confident
about and the other of which I want feedback on. I'll separate them
into two messages to keep any threads distinct. This is the one I feel
confident of.

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

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
annotated @Nullable.

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.

Thoughts?

Bill

c...@frontiernet.net

unread,
Jan 22, 2009, 12:28:39 PM1/22/09
to jsr...@googlegroups.com
Bill, I agreed with all your argumentation that inherited type qualifiers (whether implicit or explicit) should take precedence over default annotations in the current class or package - right up to where you listed the new algorithm at the end. I expected the third bullet to be second and the second to be last, given your previous discussion.

Also, then you say "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."
I would have expected either a warning or that the inherited spec would take precedence.

Furthermore, I would expect that a Nullable parameter may not be overridden to be NonNull in an overriding method.

- David

Brian Goetz

unread,
Jan 30, 2009, 3:10:39 PM1/30/09
to jsr...@googlegroups.com
> 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.

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.

Reply all
Reply to author
Forward
0 new messages