library
advancedCustom Annotations & Annotation Processing
Create and process custom annotations, understand retention policies, and use annotation processors for compile-time code generation.
Annotations are metadata attached to Java elements (classes, methods, fields, parameters). They don't change program behavior directly but are read by tools, frameworks, and compilers.
Annotations = sticky notes on code. @Override = a note saying 'this should match the parent's version.' The compiler reads the note and verifies. Runtime annotations = notes that remain attached and can be read by anyone examining the code later.
Key Concepts
1
Built-in annotations:
- @Override: compiler checks method actually overrides a superclass method
- @Deprecated: marks elements as deprecated (compiler warning)
- @SuppressWarnings: suppresses compiler warnings
- @FunctionalInterface: compiler checks interface has exactly one abstract method
2
Meta-annotations (annotations on annotations):
- @Retention: when the annotation is available: SOURCE (compiler only), CLASS (in .class file, not runtime), RUNTIME (available via reflection)
- @Target: where it can be applied: TYPE, METHOD, FIELD, PARAMETER, etc.
- @Documented: included in Javadoc
- @Repeatable: can be applied multiple times to the same element
- @Inherited: subclasses inherit the annotation from parent classes
3
Custom annotations: define with @interface. Fields are declared as methods with optional default values. Only primitives, String, Class, enums, annotations, and arrays of these are allowed as field types.
4
Processing: at runtime via reflection (getAnnotation(), isAnnotationPresent()). At compile time via annotation processors (AbstractProcessor) — used by Lombok, MapStruct, Dagger.