| Lesson 18 | Metadata Annotations in Java |
| Objective | Understand the role of metadata annotations and how to create and use them effectively in Java SE 22. |
Annotations are a form of metadata that provide information about program elements without being part of the executable logic. They differ from comments in that they can influence compilation, code generation, or runtime behavior when processed by frameworks or tools. In modern Java, annotations play a central role in declarative programming, configuration, and testing.
Annotations serve several key purposes in Java development:
@Override, help the compiler detect programming errors. For example, if a subclass method is annotated with @Override but does not match a superclass method, the compiler generates an error. Similarly, @Deprecated warns developers that an element is obsolete, and @SuppressWarnings allows suppression of specific compiler warnings.@Controller identifies a class as a web controller, and @Autowired injects dependencies automatically. Hibernate uses @Entity to mark a class as a persistent entity.@Retention(RetentionPolicy.RUNTIME), they remain available for reflection, allowing tools or frameworks to read and act on them during execution.@Data and @Mapper to automatically generate code, reducing boilerplate and improving maintainability.
All annotations begin with the @ symbol followed by the annotation name. Some annotations accept parameters enclosed in parentheses. If the only parameter is named value, the parameter name can be omitted.
@Override
public String toString() {
return "Example";
}
@MyAnnotation(value = "Sample", count = 5)
@MyAnnotation("Simplified usage when only 'value' is present")
Annotations themselves can be annotated—these are called meta-annotations. They define how and where your custom annotation behaves:
SOURCE: discarded by the compilerCLASS: recorded in the class file but not accessible at runtime (default)RUNTIME: retained and available via reflectionTYPE, METHOD, FIELD, or CONSTRUCTOR.Developers can define their own annotations to store metadata relevant to a project or framework. The following example demonstrates creating a custom annotation and accessing its values using reflection.
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface AuthorInfo {
String name();
String date();
String version() default "1.0";
}
@AuthorInfo(name = "Thomas Hauck", date = "2025-04-21", version = "2.0")
public class MyService {
@AuthorInfo(name = "Thomas Hauck", date = "2025-04-21")
public void processData() {
System.out.println("Processing data...");
}
}
import java.lang.reflect.Method;
public class AnnotationReader {
public static void main(String[] args) throws Exception {
Class<MyService> clazz = MyService.class;
// Class-level annotation
if (clazz.isAnnotationPresent(AuthorInfo.class)) {
AuthorInfo info = clazz.getAnnotation(AuthorInfo.class);
System.out.println("Class Author: " + info.name() + ", Date: " + info.date() + ", Version: " + info.version());
}
// Method-level annotation
Method method = clazz.getMethod("processData");
if (method.isAnnotationPresent(AuthorInfo.class)) {
AuthorInfo info = method.getAnnotation(AuthorInfo.class);
System.out.println("Method Author: " + info.name() + ", Date: " + info.date());
}
}
}
Class Author: Thomas Hauck, Date: 2025-04-21, Version: 2.0
Method Author: Thomas Hauck, Date: 2025-04-21
Annotations in Java provide a structured and declarative approach to embedding metadata into code. They simplify configuration, improve compiler safety, and allow frameworks to automate complex behaviors. Whether used at compile time or runtime, annotations make code more expressive, maintainable, and adaptable—hallmarks of modern Java development.