Repeatable and type annotations
Java 8 let annotations repeat, and let them appear anywhere a type does.
Open this lesson in the learning hubKey points
- Before 8, applying the same annotation twice needed a hand-written container annotation.
@Repeatablelets the compiler generate that wrapping for you.- Type annotations can sit on any type use -
List<@NonNull String>, casts,throwsclauses. - The JDK ships no null checker; type annotations exist so tools like the Checker Framework can.
- Only
RUNTIMEretention survives into a form reflection can read.
Example
import java.lang.annotation.*;
import java.util.*;
public class Main {
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Roles.class)
@interface Role { String value(); }
@Retention(RetentionPolicy.RUNTIME)
@interface Roles { Role[] value(); }
@Role("admin")
@Role("auditor")
static class Account { }
public static void main(String[] args) {
Role[] roles = Account.class.getAnnotationsByType(Role.class);
System.out.println("repeated annotations found: " + roles.length);
for (Role r : roles) {
System.out.println(" role = " + r.value());
}
// The container is generated for you
System.out.println("container : " + Account.class.getAnnotation(Roles.class));
}
}
@Repeatable is compiler sugar over a container annotation - reflection still sees the wrapper.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Java 8 Course course, and every lesson in it is listed on the Java 8 Course contents page.