[JSR308] Annotations on type variable declarations

Michael Ernst mernst at cs.washington.edu
Wed Feb 25 00:31:14 EST 2009

This message concerns annotations on type variable declarations, and in
particular how to specify whether an annotation is permitted there.

JSR 308 supports annotations on the declarations of type variables, such as

  class Foo<@Anno1 X> { ... }

Separately, JSR 308 supports annotations on uses of type variables, such as

  class Foo<X> {
    @Anno2 X myVariable = ...;

and annotations on uses of types that are not type variables:

    @NonNull String myVariable = ...;

JSR 308's new TYPE_USE enum constant of java.lang.annotation.ElementType
indicates that a given annotation may appear on a use of a type.  For
example, the NonNull annotation might be declared as follows:

  public @interface NonNull { ... }

Question:  Is it necessary to add more new enum constants to
java.lang.annotation.ElementType, to distinguish among the locations for
annotations that are exemplified by @Anno1, @Anno2, and @NonNull above?

If so, then the compiler will forbid placing an annotation in the
disallowed locations whether or not the annotation processor is being run.
If not, then the annotation processor must check explicitly.  The current
Java design already requires an annotation processor must do some such
checks.  For example, Java 5 provides no way to indicate that a particular
annotation is permitted on class declarations but not permitted on enums;
but an annotation processor can achieve this same effect by issuing an
error when it sees an annotation appears in a place that the annotation is
not supported.

A key question is whether the need for making the distinctions among the
annotation locations justify adding more enum constants (and asking users
of ElementType to understand their meaning).

Here are some possibilities.

 * ElementType.TYPE_USE permits @Anno1, @Anno2, and @NonNull.

   A type variable declaration is not really a use of a type, so in this
   design the name TYPE_USE is a bit of a misnomer and may be confusing.
   It could perhaps be renamed to, say, ElementType.TYPE_ANNOTATION.

 * ElementType.TYPE permits @Anno1.
   ElementType.TYPE_USE permits @Anno2 and @NonNull.

   This re-uses the existing ElementType.TYPE constant, which applies to
   type declarations.  This fits because, just as with class/iterator/enum
   declarations, a type variable declaration introduces a symbol that may
   afterward be used as a type.  A difference is that a type variable
   declaration only introduces a name for an existing type, whereas the
   other declarations introduce both a new type and a name.

 * new enum constant ElementType.TYPE_PARAMETER permits @Anno1.
   ElementType.TYPE_USE permits @Anno2 and @NonNull.

I don't think it makes sense to distinguish between the locations
exemplified by @Anno2 and @NonNull.


PS:  JSR 308 supports annotations on type variable declarations because
people have found uses for it.  If those other people can remind me of
those uses, I'll note them in the design document.  That will also make our
discussion more concrete.

(The checkers that are currently distributed with the Checker Framework
don't make use of annotations on declarations of type variables.  To make
sure that the type argument supplied as X has annotation @Anno1, one would
  class Foo<X extends @Anno1 Object> { ... }
But other type systems have different needs.)

More information about the JSR308 mailing list