The @Target Meta-Annotation
An annotation type declaration can specify the contexts in which the annotation is applicable. This is controlled by the meta-annotation type java.lang.annotation.Target and the element type constants defined by the enum type java.lang.annotation.Element-Type, shown in Table 25.2. The meta-annotation type Target is an array-valued single-element meta-annotation type—that is, it has a single value() element of type ElementType[] to specify contexts in which the annotation is applicable, meaning multiple ElementType values can be specified to indicate multiple contexts.
Table 25.2 The ElementType Values for the @Target Meta-Annotation
Constants defined by the ElementType enum | Description | |
1. | ANNOTATION_TYPE | The annotation can be applied to annotation type declarations. @Tag @interface Status {} |
2. | CONSTRUCTOR | The annotation can be applied to constructor declarations. @Tag public Item() {} |
3. | FIELD | The annotation can be applied to field declarations, such as instance and static variables, or enum constants. Click here to view code image @Tag public static final int YEAR = 2021; enum Size { @Tag S, @Tag M, @Tag L, @Tag XL } |
4. | LOCAL_VARIABLE | The annotation can be applied to local variable declarations, including loop variables of for statements and resource variables of try-with-resources statements. Click here to view code image @Tag String localBarber = “Director’s Cut”; for (@Tag int i : intArray) {} try (@Tag var resource = new CloseableResource()) {} |
5. | METHOD | The annotation can be applied to method declarations (including elements of annotation types). Click here to view code image @Tag boolean passed() { return true; } @Tag String[] value(); |
6. | MODULE | The annotation can be applied to a module declaration in a module-info.java source file. @Tag module com.passion {} |
7. | PACKAGE | The annotation can be applied to a package declaration in a source file. Best practice is to specify package-related annotations in a file named package-info.java. Click here to view code image @Tag package com.passion.logic; |
8. | PARAMETER | The annotation can be applied to formal and exception parameter declarations in constructors, methods, lambda expressions, and catch blocks. Click here to view code image double circleArea(@Tag double r) { return Math.PI*r*r; } Predicate<String> p = (@Tag var str) -> str.length() < 10; try {} catch (@Tag Exception ex) {} |
9. | TYPE | The annotation can be applied to type declarations: class, interface (including annotation type), and enum declarations. Click here to view code image @Tag class Gizmo {} @Tag interface Reparable {} @Tag enum Direction {LEFT, RIGHT} @Tag @interface Validate {} |
10. | TYPE_PARAMETER | The annotation can be applied to type parameter declarations of generic classes, interfaces, methods, and constructors. Click here to view code image class Box<@Tag E> {} interface Eatable<@Tag E> {} <@Tag E extends Comparable<E>> void comparison(E e) {} <@Tag E> Item(E e) {} |
11. | TYPE_USE | The annotation can be applied in any type context in declarations and expressions where a type can be used. Click here to view code image class X extends @Tag Y implements @Tag IZ {} java.lang. @Tag String strOp() { return “ok”; } @Tag int compute() { return (@Tag int) 3.14; } java.lang. @Tag Integer iRef1 = 100; @Tag Integer iRef2 = 100; void passItOn() throws @Tag Exception {} @Tag int[] array1; // Annotates primitive type int int @Tag [] array2; // Annotates array type int[] int @Tag [][] array3; // Annotates array type int[][] |
The target values of the ElementType constants in Table 25.2 are categorized by the two contexts where annotations can be applied: declaration context and type context.