Annotations
An Annotation is a way of including metadata or information within the source code in a structured format. Generally, annotations do not directly affect the execution of the program. Instead, they provide hints or instructions for the compiler or for specific frameworks to analyze and process the code, either at compile-time or runtime.
They behave somewhat similarly to standard comments (// or /* */), with the powerful difference that annotations can be read and processed by machines (like compilers or libraries).
1. Standard Annotations
Java provides several built-in standard annotations out of the box:
@Override: Informs the compiler that this method is overriding a method in the superclass. If you make a typo or if no such method exists in the parent class to override, the compiler will throw an error.@Deprecated: Marks a field or method that is no longer recommended for use. If it is used, the compiler generates a warning.@SuppressWarnings: Prevents the compiler from showing specific warning messages.
class Parent {
public void printMessage() {
System.out.println("Hello");
}
}
class Child extends Parent {
@Override // Tells the compiler this is an overriding method
public void printMessage() {
System.out.println("Hello, Child!");
}
@Deprecated // Recommends not using this method anymore
public void oldMethod() {
System.out.println("Old method");
}
}
2. Meta Annotations
Meta Annotations are annotations meant for annotations. They are used when defining a custom annotation to specify exactly where and how that new annotation can be applied, and how long it should be retained.
@Target: Specifies the elements to which the annotation can be applied (Class, Method, Field, etc.).@Retention: Indicates how long annotations are to be retained (SOURCE,CLASS,RUNTIME).@Documented: Indicates that annotations with a type are to be documented by javadoc and similar tools.@Inherited: Indicates that an annotation type is automatically inherited by subclasses.
3. Creating Custom Annotations
Developers can create custom annotations to work alongside frameworks (like Spring) or the Reflection API, triggering specialized behaviors and logic.
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE}) // Can be applied to both Class and Method
@Retention(RetentionPolicy.RUNTIME) // Maintained until runtime
public @interface MyCustomAnnotation {
String value() default "Default Value"; // Element with a default value
int count() default 1;
}
Utilizing Annotations via Reflection
You can read the information from this created annotation at runtime using Java's Reflection API.
@MyCustomAnnotation(value = "Test Class", count = 5)
public class AnnotationTest {
public static void main(String[] args) {
// Retrieve the 'MyCustomAnnotation' applied to AnnotationTest class
MyCustomAnnotation anno = AnnotationTest.class.getAnnotation(MyCustomAnnotation.class);
System.out.println("Value: " + anno.value()); // Test Class
System.out.println("Count: " + anno.count()); // 5
}
}
The core foundation of modern Java technology stacks, such as the Spring Framework and JPA, relies heavily on this powerful Annotation processing feature!