11.3 Custom Annotations Explained
Custom annotations in Java SE 11 allow developers to define their own annotations to provide specific metadata for their applications. These annotations can be used to convey additional information to the compiler, tools, or runtime environments, enhancing the functionality and maintainability of the code.
Key Concepts
1. Defining Custom Annotations
Custom annotations are defined using the @interface
keyword. They can have elements that define their behavior, such as default values and data types.
Example
public @interface MyCustomAnnotation { String value() default "Default Value"; int count() default 1; }
2. Applying Custom Annotations
Custom annotations can be applied to classes, methods, fields, parameters, and other elements. They provide additional information that can be used by tools or frameworks.
Example
@MyCustomAnnotation(value = "Custom Value", count = 5) public class MyClass { @MyCustomAnnotation public void myMethod() { // Method implementation } }
3. Meta-Annotations for Custom Annotations
Meta-annotations are annotations that are applied to other annotations. They define how the target annotation should be processed. Common meta-annotations include @Retention
, @Target
, @Documented
, and @Inherited
.
Example
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyCustomAnnotation { String value() default "Default Value"; }
4. Retention Policies
Retention policies define the lifecycle of an annotation. The three retention policies are SOURCE
, CLASS
, and RUNTIME
. They determine whether the annotation is available at compile time, class loading time, or runtime.
Example
@Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation { String value() default "Default Value"; }
5. Target Types
Target types specify the elements to which an annotation can be applied. These include TYPE
, METHOD
, FIELD
, PARAMETER
, and others. The @Target
meta-annotation is used to define these targets.
Example
@Target(ElementType.METHOD) public @interface MyCustomAnnotation { String value() default "Default Value"; }
6. Using Custom Annotations with Reflection
Custom annotations can be accessed at runtime using Java Reflection. This allows developers to inspect the annotations and perform actions based on their values.
Example
public class AnnotationProcessor { public static void processAnnotations(Class<?> clazz) { for (Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(MyCustomAnnotation.class)) { MyCustomAnnotation annotation = method.getAnnotation(MyCustomAnnotation.class); System.out.println("Method: " + method.getName() + ", Value: " + annotation.value()); } } } }
Examples and Analogies
Think of custom annotations as sticky notes with specific instructions that you attach to your code. For example, you might create an annotation called @PerformanceCritical
to indicate that a method is performance-sensitive and should be optimized. This is like a sticky note that says, "This method needs extra attention for performance."
Meta-annotations are like rules for how these sticky notes should be treated. For example, the @Retention
meta-annotation is like setting a timer for how long the sticky note should be visible, while the @Target
meta-annotation is like specifying where the sticky note can be placed.
By mastering custom annotations, you can create powerful and flexible metadata for your Java SE 11 applications, enhancing their functionality and maintainability.