All topics
library
advanced

Custom 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.