Working with Annotations

1. Understanding Built-in Annotations

AnnotationPurpose
@OverrideMethod overrides supertype
@Deprecated(since, forRemoval)Mark for removal
@SuppressWarnings("unchecked")Silence compiler warnings
@FunctionalInterfaceSingle-abstract-method interface
@SafeVarargsGeneric varargs are safe

2. Using @Override

UseDetail
Catches typosCompile error if not actually overriding
Required forInterface methods (Java 6+)

3. Using @Deprecated

Example: Deprecation

@Deprecated(since = "11", forRemoval = true)
public void oldMethod() { ... }
ElementDetail
sinceVersion deprecated in
forRemovaltrue → terminal deprecation

4. Using @SuppressWarnings

ValueSuppresses
"unchecked"Generic cast warnings
"deprecation"Deprecated API use
"rawtypes"Raw type warnings
"all"All (avoid)

5. Using @FunctionalInterface

AspectDetail
EffectCompile error if not exactly one abstract method
Doesn't preventDefault/static methods

6. Creating Custom Annotations

Example: Custom annotation

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Audited {
    String value() default "";
    String[] roles() default {};
    int level() default 1;
}
ElementAllowed Types
Element typesPrimitives, String, Class, enum, annotation, arrays of these
value()Special: can be omitted in usage

7. Using @Target

ElementTypeApplies To
TYPEClass/interface/enum
METHODMethods
FIELDFields
PARAMETERMethod params
CONSTRUCTORConstructors
TYPE_USEAny type usage (Java 8+)
MODULEModules (Java 9+)

8. Using @Retention

PolicyAvailable
SOURCECompile time only (e.g., @Override)
CLASSIn .class but not at runtime (default)
RUNTIMEAvailable via reflection

9. Using @Documented

AspectDetail
EffectAnnotation appears in Javadoc

10. Using @Inherited

AspectDetail
EffectSubclass inherits class-level annotation
LimitationOnly for class types, not interfaces or methods

11. Using @Repeatable JAVA 8+

Example: Repeatable

@Repeatable(Schedules.class)
@interface Schedule { String day(); }
@interface Schedules { Schedule[] value(); }

@Schedule(day = "MON")
@Schedule(day = "WED")
class Job {}
StepDetail
1Define container annotation with value() array
2Annotate child with @Repeatable(Container.class)

12. Processing Annotations at Runtime

Example: Reflection

Class<?> cls = MyService.class;
if (cls.isAnnotationPresent(Audited.class)) {
    Audited a = cls.getAnnotation(Audited.class);
    System.out.println(a.value());
}
for (Method m : cls.getDeclaredMethods()) {
    Audited a = m.getAnnotation(Audited.class);
    if (a != null) ...
}
MethodReturns
getAnnotation(cls)Single annotation
getAnnotationsByType(cls)Repeatable annotations
isAnnotationPresent(cls)boolean

13. Using Annotation Processors

AspectDetail
APIjavax.annotation.processing
Base classExtend AbstractProcessor
Run timeCompile time only
ExamplesLombok, Dagger, MapStruct, Immutables