Declaring custom annotations
The @interface syntax, element types, defaults, value() shorthand, and marker annotations.
Declaring an annotation type
Annotations are declared with @interface (not interface). Elements look like zero-argument methods with optional default values:
public @interface Review {
String author(); // required — no default
String comment() default "";
int priority() default 1; // defaults to 1 if omitted
}
Using the annotation:
@Review(author = "alice", comment = "needs tests", priority = 2)
public void processOrder() { /* ... */ }
Element type rules
Annotation element types are restricted to:
- Primitives (int, boolean, etc.)
- String
- Class (e.g. Class<?>)
- An enum type
- Another annotation type
- A 1D array of any of the above
Complex types like List<String> are not allowed.
The value() shorthand
If an annotation has a single element named value (and all other elements have defaults), callers can omit the element name:
public @interface Tag {
String value();
}
@Tag("important") // shorthand for @Tag(value = "important")
public void foo() {}
Marker annotations
An annotation with no elements is a marker annotation — its presence alone conveys information:
public @interface ThreadSafe {} // marker — no elements
@ThreadSafe
public class SafeCounter { /* ... */ }