Using annotation with @Target(TYPE_USE) on type declaration

Alex Buckley alex.buckley at
Tue Jun 27 18:47:39 UTC 2017

On 6/27/2017 7:54 AM, Gunnar Morling wrote:
> I've an annotation type whose only supported target is ElementType.TYPE_USE:
>      @Target(ElementType.TYPE_USE)
>      public @interface MyAnno {}
> To my surprise I can use this annotation on the definition of a class,
> whereas I'd have expected a compilation error:
>      @MyAnno
>      public class Foo {}
> I can't seem to find the JLS wording that'd suggest that TYPE_USE
> allows usage of the annotation on a type definition.
> " @Target" [1] mentions eight declaration contexts (which don't
> seem to apply here as per the supported element type) and 16 type
> contexts which are described in "4.11. Where Types Are Used" [2]. They
> are represented by TYPE_USE, but none of these seem to match the the
> declaration of type Foo.

1. JLS is trying to make {declaration,type} contexts in the 
language correspond to constants in the ElementType API. A type 
declaration context corresponds to TYPE, and the 16 type contexts 
corresponds to TYPE_USE. Notice the correspondence is one-way.

2. The API spec for ElementType is trying to make constants in the 
ElementType API correspond to {declaration,type} contexts in the 
language. The TYPE_USE constant corresponds to more contexts than the 
JLS said correspond to it:

   "The constant TYPE_USE corresponds to the type contexts in JLS 4.11,
    as well as to two declaration contexts: type declarations
    (including annotation type declarations) and
    type parameter declarations."  [Rationale follows]

3. You're now wondering why JLS doesn't "just" make a type 
declaration context correspond to both TYPE and TYPE_USE. The answer is 
that I wanted to keep the correspondence between contexts and constants 
as straightforward as possible in the JLS. This was one of many 
techniques for managing the complexity of the specification as it gained 
support for type annotations and repeating annotations in SE 8.

4. OK, so why does the JLS allow @MyAnno on the declaration of class 
Foo? Because JLS 9.7.4 says the following, which "implements" the 
ElementType API spec's belief that TYPE_USE corresponds to type 

   "It is a compile-time error if an annotation of type T is
    syntactically a modifier for: ... a class, interface, or enum
    declaration, but T is not applicable to type declarations or
    type contexts"

5. The JLS9 draft available at has some words in 9.7.4 to 
explain this multi-role of TYPE_USE.


More information about the compiler-dev mailing list