Implementing Custom Annotations in Java
Fundamentals of Java Annotations
Annotations provide a mechanism for adding metadata to Java code, offering supplemental information that can be processed by compilers, tools, and runtime environments. They are syntactically distinguished by an @ symbol preceding the annotation name, as seen in @Override and @Deprecated.
Defining Custom Annotations
New annotation types are declared using the @interface keyword.
@interface CustomAnnotation {
String identifier();
int priority() default 5;
}
Meta-Annotations
Meta-annotations are annotations applied to other annotations, governing their scope and behavior.
@Target
Specifies the kinds of program elements to which an annotation can be applied, using values from the ElementType enumeration.
@Target({ElementType.CLASS, ElementType.FIELD})
public @interface ScopeAnnotation {
}
@Retention
Defines the annotation's lifecycle, inidcating how long the annotation information is retained.
RetentionPolicy.SOURCE: Discarded during compilation.RetentionPolicy.CLASS: Retained in the bytecode but not accessible at runtime.RetentionPolicy.RUNTIME: Available at runtime via reflection.
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimeAnnotation {
}
@Documented
Indicates that the annotation should be included in the generated Javadoc documentation.
@Documented
public @interface DocAnnotation {
}
@Inherited
Specifies that if an annotation is applied to a class, its subclasses will also be considered as having that annotation.
@Inherited
public @interface InheritableAnnotation {
}
Practical Application: Creating and Processing a Custom Annotation
1. Annotation Definition
Define an annotation to document method details.
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ProcedureMetadata {
String creator() default "Anonymous";
String lastModified();
int iteration() default 1;
}
2. Applying the Annotation
Use the custom annotation to tag a method.
public class DemoComponent {
@ProcedureMetadata(creator = "devTeam", lastModified = "2024-05-15", iteration = 3)
public void executeTask() {
System.out.println("Executing annotated procedure.");
}
}
3. Runtime Processing via Reflection
Retrieve and display annotation data at runtime.
import java.lang.reflect.Method;
public class AnnotationProcessor {
public static void main(String[] args) {
DemoComponent component = new DemoComponent();
Method[] allMethods = component.getClass().getDeclaredMethods();
for (Method m : allMethods) {
if (m.isAnnotationPresent(ProcedureMetadata.class)) {
ProcedureMetadata meta = m.getAnnotation(ProcedureMetadata.class);
System.out.println("Procedure: " + m.getName());
System.out.println("Author: " + meta.creator());
System.out.println("Modified On: " + meta.lastModified());
System.out.println("Revision: " + meta.iteration());
}
}
}
}