Element Modifiers for Annotation Type Elements
The modifiers allowed for an annotation type element are analogous to the modifiers that can be specified for an abstract method declaration in a normal interface. The only access modifier that can be specified for an annotation type element is public; otherwise, the accessibility is implicitly public. The modifier abstract is also implied, and typically not specified in the annotation type element declaration. The elements of the TaskInfo annotation type are implicitly public and abstract.
Element Type of Annotation Type Elements
The element type of an annotation type element can be any one of the following:
- A primitive type
- A String
- The class Class
- An enum type
- An annotation type
- A one-dimensional array whose element type is one of the above types
The code below illustrates declaring the element type of an annotation type element. An example of each type that is allowed as the return type of an annotation type element is shown, together with the specification of a default value for each annotation type element.
public @interface MultiElementAnnotationType {
public enum Priority { LOW, NORMAL, HIGH };
public int certificationLevel() default 1; // int
String date() default “2021-01-11”; // String
Class<? extends PrettyPrinter> pp()
default AdvancedPrettyPrinter.class; // type Class
Priority priorityLevel() default Priority.NORMAL; // enum Priority
Tag annotate() default @Tag; // Annotation type
int[] value() default {10, 20, 30}; // Array, int[]
}
// Auxiliary classes:
class PrettyPrinter {}
class AdvancedPrettyPrinter extends PrettyPrinter {}
The declaration of the ProblematicAnnotationType annotation type below shows examples of illegal declarations of annotation type elements.
@interface ProblematicAnnotationType {
StringBuilder message(); // Illegal return type.
int[][] voting(); // Only one-dimensional array allowed.
String value; // Missing parentheses.
private Thread.State state(); // Only public can be specified.
}
The code below shows an annotation which is used as an element type within another annotation. This relationship between annotations is sometimes described as a contained annotation type (1) and a containing annotation type (2). This relationship is further explored when we discuss repeatable annotations (p. 1575).
public @interface MusicMeta { // (1) Contained annotation type
String value();
}
public @interface ArtistMeta { // (2) Containing annotation type
MusicMeta value(); // Annotation type from (1).
}