Working with Annotations

1. Using Built-in Annotations

AnnotationPurpose
@OverrideCompile-time check of override
@Deprecated(since, forRemoval)Mark obsolete API
@SuppressWarnings("unchecked")Silence specific warnings
@FunctionalInterfaceEnforce SAM
@SafeVarargsSuppress generic varargs warning
@NativeJNI field marker

2. Creating Custom Annotations (@interface)

ElementSyntax
Declarationpublic @interface Audit { }
ElementString value() default "";
Allowed typesprimitive, String, Class, enum, annotation, array
Single-element shortcutname value → use @Audit("info")

Example: Custom annotation

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {
    String value() default "";
    Level level() default Level.INFO;
}

3. Using Meta-Annotations

MetaEffect
@TargetAllowed element types
@RetentionVisibility (SOURCE/CLASS/RUNTIME)
@DocumentedInclude in Javadoc
@InheritedSubclass inherits class-level annotation
@RepeatableAllow repeated use

4. Setting Retention Policies

PolicyAvailableExample
SOURCECompiler only@Override
CLASSIn .class, not loadedDefault; build-time tools
RUNTIMEReflective accessDI, ORM, validation

5. Defining Annotation Elements

FeatureDetail
DefaultString value() default "";
ArrayString[] tags() default {};
EnumLevel lvl() default Level.INFO;
ClassClass<?> type() default Object.class;
Nested annotationAllowed
RequiredNo default → must specify

6. Using Repeating Annotations (@Repeatable)

StepCode
Annotation@Repeatable(Roles.class) @interface Role { String value(); }
Container@interface Roles { Role[] value(); }
Readmethod.getAnnotationsByType(Role.class)

7. Processing Annotations at Runtime

APIPurpose
cls.isAnnotationPresent(A.class)Check existence
cls.getAnnotation(A.class)Get instance
cls.getDeclaredAnnotations()All on this element
cls.getAnnotationsByType(A.class)Repeatable

Example: Audit interceptor

for (Method m : svc.getClass().getMethods()) {
    Audit a = m.getAnnotation(Audit.class);
    if (a != null) log.info("audit:{} method={}", a.value(), m.getName());
}

8. Creating Type Annotations (@Target(TYPE_USE))

Use SiteExample
Cast(@NonNull String) obj
GenericsList<@NonNull String>
throwsvoid m() throws @Critical Exception
Receivervoid m(@ReadOnly Foo this)

9. Understanding Annotation Inheritance

ScenarioInherited?
Class with @Inherited annotationYes (class hierarchy only)
Interface annotationsNo
Method overridesNo (always)
Field annotationsNo

10. Using @SafeVarargs for Heap Pollution

RuleDetail
Wherefinal/static/private methods, constructors, Java 9+ private instance
WhenBody never writes to varargs array nor leaks it
EffectSuppresses unchecked warning at call site

Example: Safe varargs

@SafeVarargs
public static <T> List<T> listOf(T... elements) {
    return List.of(elements);
}