Introduces an annotation type to the program, which can be used to annotate targeted elements.
An annotation declaration consists of:
1 | modifier-list @
interface name {
annotation-members }
|
where...
modifier-list | is a possibly empty set of keywords and annotations that can
contain:
in any order. |
name | is any valid identifier that is not the same as a sibling type or a surrounding type, if the annotation is not top-level. |
annotation-members | is any number of:
in any order. |
1 A declaration of an annotation type.
An annotation declaration introduces an annotation type to the program.
Annotation types are interface
s that can
be used to annotate program elements.
interface
.
They can be used as interface
s in most respects (e.g. they
can be instantiated with anonymous classes, lambda expressions, and
used as a variable type), but are designed to be used primarily for
annotating elements. If a type declares that it implement
s
an annotation, a warning is issued.
@Target
Behavior
An annotation declaration may specify a set of targets that
determines what program elements the annotation may be used on using
the java.lang.annotation.Target
meta annotation.
@Target
annotation is applied to an annotation
declaration, the declaration may be used to annotate the program
elements specified in the @Target
annotation.
More precisely, such an annotation may apply to a program element if
any of the targets specified permits the annotation to be used on that
element.
@Target
is specified with an
empty set, the annotation may not be applied to any program
element, for example @Target({})
. For uses of this, see note 1 below.
@Target
Application
The @Target
meta-annotation, if used, must be located in
the modifier-list of the annotation
declaration it applies to. The meta-annotation must be supplied a
(possibly empty) array of java.lang.annotation.ElementType
values, without duplicates, for the value()
element of @Target
.
@Target
annotation may never include
duplicate elements in the array passed as an argument for its value()
element. This is enforced by the compiler. The following: @Target({ElementType.TYPE, ElementType.TYPE})
@interface X {}
results in a compiler error.
The following table lists each annotation target along with a description of what elements it allows an annotation to apply to:
Target | Description |
---|---|
Type | any class , enum , and interface
declarations (including any @interface annotation
declarations).
|
Annotation Type | any @interface annotation declarations. The
Type target is a superset of this target; declaring an
annotation with both Type and Annotation Type as
targets is redundant. This target is primarily used to declare
meta-annotations, as annotations with only this target may
not be applied to any type; just other annotations' declarations.
|
Method | any method declaration, including abstract
declarations and annotation element declarations.
|
Constructor | any constructor declaration. |
Field | any field declaration, including constants
declared in @interface s and enum
constants. (Note that annotations targeting fields can be used on
their own member constants.) Formally, annotations
targeting fields apply to the declaration that declares a
field, or set of fields.
In practice, each reflection |
Parameter | any method parameter (not including receiver parameters). Receiver parameters are not formal
parameters, so they may not be annotated by virtue of the
annotation being declared to target a parameter.
Receiver parameters allow only their type to be annotated, so annotations contained in their syntax must target type use. For receiver parameter syntax, see, Receiver Parameters. |
Local Variable | any local variable declaration, including those
in the header of a for loop or try -with-resources
statement. Annotations of this target apply to the declaration
that declares a local variable, or possibly a list of local
variables.
Since local variables cannot be accessed through reflection, such detail has no programmatic impact. |
Package | implementation-dependent package declaration. Syntactically (disregarding semantic restrictions),
annotations targeting packages may be placed in front of the package
keyword on any package declaration in any file, however, each
package is subject to the constraint that only one such declaration
may be annotated.
Java provides implementations with liberty for upholding this
requirement. (File-based) implementations typically consider a
canonical package declaration in a file named |
Type Parameter | any type parameter declaration. |
Type Use | the use of a type. For details, see annotations. |
Annotations may declare, as members, any number of the following:
Each member may be located anywhere directly in the body of the annotation declaration.
Each annotation element in an annotation specifies an attribute of the annotation. They are described in detail here.
@Target({})
.
Such an annotation will raise a compile-time error if used on any
element.
Nevertheless, the annotation may still be used as an element for other annotations, e.g.:
@Target({})
@interface Author {
String authorName();
String authorEmail();
int authorAge();
}
@interface Authors {
Author[] value();
}
The @Authors
annotation may then be applied to any
element (except type parameter declarations) while the @Author
annotation may not be applied to any.
Additionally, note that the surviving interface
features
of annotations may still be used with such annotations. For example,
variables can be declared with the annotation as a type, and the
annotations can even be used to create anonymous classes:
Author a = new Author() {
@Override
public Class<? extends Annotation> annotationType() {
return null;
}
@Override
public String authorName() {
return null;
}
@Override
public String authorEmail() {
return null;
}
@Override
public int authorAge() {
return 0;
}
};
@Target
annotation must not contain duplicate ElementType
values for its value()
element, even when not used to
annotate an annotation declaration. For example, the uniqueness
constraint of ElementValues
still holds, even in the
following @Target
use: public @interface Note {
Target value() default @Target({ ElementType.TYPE, ElementType.TYPE });
}
The above code raises a compilation error.