Using annotation with @Target(TYPE_USE) on type declaration
Alex Buckley
alex.buckley at oracle.com
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.
>
> "9.6.4.1 @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 9.6.4.1 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 9.6.4.1 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
declarations:
"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
http://cr.openjdk.java.net/~mr/jigsaw/spec/ has some words in 9.7.4 to
explain this multi-role of TYPE_USE.
Alex
More information about the compiler-dev
mailing list