Annotation definitions and usage
Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.
Annotations are metadata that can associate different elements and structures in your code without directly affecting the elements it annotates, but can be recognized by the compiler and used in combination with reflection, etc. A simple annotation is declared as follows, and the @Interface keyword introduces a new annotation type.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TaskName {
String value();
}
Annotations can declare properties with and without default values
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TaskName {
String value();
int taskId() default 0;
}
If an annotation declares a property that has no default value, then the annotation property value should be provided wherever the annotation is applied.
@TaskName (name = "test")
If the annotation has only one attribute and is a value then the name can be omitted, but the value must be specified, for example: @TaskName (“test”)
public @interface TaskName {
String value();
}
Retention policy
Each annotation has a feature called RetentionPolicy, which is an enumeration (RetentionPolicy type) of a set of combinations of policies on how to retain annotations.
strategy | describe |
---|---|
CLASS | Annotations are recorded by the compiler in a class file, but do not need to be retained by the virtual machine at run time (i.e., they do not exist at run time) |
RUNTIME | Annotations are recorded by the compiler in a class file and are retained by the virtual machine at run time, so they can be retrieved through reflection |
SOURCE | Annotations are discarded by the compiler (that is, they are only kept in the source code and do not exist in the class file) |
The following code, RetentionPolicy.Runtime, will ensure that the annotations are present during compilation and in the running application.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TaskName {
String value();
}
The element type
Each annotation must have an ElementType to which it can apply, and the ElementType is defined as an enumeration of a set of possible element types.
The element type | describe |
---|---|
ANNOTATION_TYPE | Indicate that annotations can be used for annotation type declarations (applied to other annotations) |
CONSTRUCTOR | Indicates that annotations can be used for constructor declarations |
FIELD | Indicates that annotations can be used for field/field (including enumeration constants) declarations |
LOCAL_VARIABLE | Marking annotations can be used for local variable declarations |
METHOD | Indicate that annotations can be used for method declarations |
PACKAGE | Marking annotations can be used for package declarations |
PARAMETER | Marking annotations can be used for parameter declarations |
TYPE | Indicates that annotations can be used for declarations of classes, interfaces (including annotation types), and enumeration types |
TYPE_PARAMETER | Indicates that annotations can be written in declarations of type variables |
TYPE_USE | Indicates that the annotation can be written in any statement that uses a type (eg: type in a declaration statement, generic, and cast statement) |
Annotations can use the @Target annotation to declare multiple element types associated with them
Usage, for example,
Reflections reflections = new Reflections("com.package.test"); for (Class<? > clazz : reflections.getTypesAnnotatedWith(TaskName.class)) { TaskName taskname = clazz.getAnnotation(TaskName.class); String keyString = taskname.value(); }