Annotation Declarations

Introduces an annotation type to the program, which can be used to annotate targeted elements.

Syntax

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:
  • one of public, protected, or private,
  • abstract,
  • static,
  • strictfp,
  • and any number of annotations that are applicable to the declaration,

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.

Syntax Elements

1 A declaration of an annotation type.

Usage

An annotation declaration introduces an annotation type to the program. Annotation types are interfaces that can be used to annotate program elements.

Annotations are formally a type of interface. They can be used as interfaces 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 implements an annotation, a warning is issued.

Targets

@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.

Note that if @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.

The @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 @interfaces 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 Field object of a single declaration, annotated with an annotation that targets fields, will expose the annotation through Field#getAnnotations() and similar methods.

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 package-info.java, within the package being annotated, whose contents begin with the package declaration, possibly with annotations. Such implementations may disallow the annotated package declaration to be placed elsewhere.

Type Parameter any type parameter declaration.
Type Use the use of a type. For details, see annotations.
For a more detailed analysis, refer to the relevant sections in Annotations.

annotation-members

Annotations may declare, as members, any number of the following:

Each member may be located anywhere directly in the body of the annotation declaration.

Annotation Elements

Each annotation element in an annotation specifies an attribute of the annotation. They are described in detail here.

Nested Types

Constants

Examples

Notes

  1. Annotations may be declared so that they cannot be applied to other elements using the meta-annotation @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;
    	}
    };
  2. The @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.