Retention and Target
Retention: how long an annotation lives
Not every annotation needs to reach the running program.
The @Retention meta-annotation defines how long information about an annotation use should be preserved.
RetentionPolicy.SOURCE— the annotation is needed only in source code and is discarded by the compiler.RetentionPolicy.CLASS— it is stored in the class file but is not required to be available through reflection at runtime. This is the default policy.RetentionPolicy.RUNTIME— it is preserved until runtime and can be read through reflection.
@Retention(RetentionPolicy.RUNTIME)
public @interface Audit {
String action();
}
If an application must discover @Audit at runtime,
that annotation needs the RUNTIME policy.
Target: where an annotation is allowed
The @Target meta-annotation restricts the locations where a custom annotation may be used.
This makes its purpose explicit and lets the compiler catch incorrect usage.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {
String action();
}
Now @Audit can be placed on a method, but cannot accidentally be attached to a field or class.
If several locations are valid, an array of values is passed to @Target.
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Marker {
}
The ElementType values include targets for types, fields, methods, parameters,
constructors, local variables, modules, record components, type parameters, and type uses.
Choose only the targets that actually make sense for the metadata being defined.