Java 8 的 @Repeatable 注解支持同一声明处多次使用相同注解,需配合容器注解(如 @Roles),该容器必须声明名为 value 的目标注解类型数组,运行时推荐用 getAnnotationsByType() 获取。

Java 8 引入了 @Repeatable 注解,让同一个注解可以在同一声明处多次使用,但前提是必须配合一个“容器注解”(container annotation)——它本身是一个普通注解,用于容纳多个同类型注解的数组。
为什么需要 @Repeatable?
在 Java 8 之前,若想在类或方法上多次使用同一注解(比如多个 @Role("admin")、@Role("user")),只能手动定义一个“容器注解”,例如 @Roles({@Role("admin"), @Role("user")})。这种方式冗余且不直观。@Repeatable 的作用就是让 JVM 自动将多个重复注解收集到指定的容器注解中,语法更简洁、语义更清晰。
@Repeatable 的基本用法
要使自定义注解支持重复添加,需两步:
- 定义目标注解,并用
@Repeatable(XXX.class)标明其容器类型 - 定义对应的容器注解,该注解必须声明一个名为
value的元素,类型为当前注解类型的数组
示例:
立即学习“Java免费学习笔记(深入)”;
@Repeatable(Roles.class)
public @interface Role {
String value();
}
public @interface Roles {
Role[] value();
}
这样就可以在类上写:
@Role("admin")
@Role("user")
public class UserService { }
JVM 会自动将其等价于:@Roles({@Role("admin"), @Role("user")})。
容器类的关键约束
容器注解不是任意写的,必须满足以下条件,否则编译报错:
- 必须是
@interface,即真正的注解类型 - 必须声明一个名为
value的元素(不能是其他名字) -
value的类型必须是被@Repeatable标注的注解类型的数组(如Role[]) - 容器注解本身不能也标注
@Repeatable(不支持嵌套重复)
注意:容器注解可以有其他元素(如 String version() default "1.0";),但只有 value 是必需且受框架识别的。
运行时获取重复注解
反射 API 提供了专门方法来安全读取重复注解:
-
getAnnotationsByType(Role.class):推荐使用,返回所有@Role实例(自动展开容器) -
getAnnotation(Roles.class):可直接获取容器注解,再调用value()取出数组 -
getAnnotations()不会包含@Role,只返回容器注解(如@Roles)
所以实际开发中应优先用 getAnnotationsByType(),它屏蔽了容器细节,语义更自然。


















