This compiles perfectly even though the following annotation is not supposed to be used as a declaration annotation.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// Foo annotation
@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@interface Foo {}
@Foo
class Person {}
@Foo
interface Emittable() {}
In the above example, the Foo
annotation type is used in the declaration contexts of Person
and Emittable
types, even though it is targeted only for type contexts, and the funny thing is that the code compiles just fine and runs perfectly Does it mean that ElementType.TYPE_USE
also covers the declaration contexts? According to the Java 14 Language Specification, ElementType.TYPE_USE
does not cover any declaration contexts. What am I missing?
The currently-accepted answer is incorrect.
The relevant documentation is at https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html and says
The constant
TYPE_USE
corresponds to the 15 type contexts in JLS 4.11, as well as to two declaration contexts: type declarations (including annotation type declarations) and type parameter declarations.
In other words, TYPE_USE
is a special case. The rationale for is that when defining a type qualifier, programmers may often want to write it on declarations as well as uses.
This is laid out in https://docs.oracle.com/javase/specs/jls/se14/html/jls-9.html#jls-9.7.4 which says:
two of the nine clauses - for class, interface, enum, and annotation type declarations, and for type parameter declarations - mention "... or type contexts" because it may be convenient to apply an annotation whose type is meta-annotated with
@Target(ElementType.TYPE_USE)
(thus, applicable in type contexts) to a type declaration.
The currently-accepted answer quotes text that is about a different matter: how to interpret the annotations in
class C {
@MyDeclAnno @MyTypeAnno Object myField;
}
where MyDeclAnno
is a declaration annotation and MyTypeAnno
is a type annotation.
The JLS grammar parses both annotations on the declaration. However, the text quoted in the currently-accepted answer notes that @MyTypeAnno
as is actually applied to the type Object
whereas @MyDeclAnno
is actually applied to the declaration of the field myField
.