java 8 的 @repeatable 注解支持同一声明上多次使用同一注解,需定义目标注解(如 @role)和容器注解(如 @rolecontainer),二者元注解必须一致,容器仅含 value() 返回目标注解数组,运行时通过 getannotationsbytype() 获取全部实例。

Java 8 引入了 @Repeatable 注解,允许同一个注解在同一个声明上多次使用,而无需包裹在容器注解中。要正确使用它,关键在于定义一对配合工作的注解:一个可重复的注解(目标注解),和一个容纳它的容器注解。
定义可重复注解的两个必要组件
必须同时定义两个注解:被重复使用的注解本身,以及它的“容器”注解。容器注解需满足:类型为数组、value 字段返回该注解类型的数组、且自身用 @Repeatable(目标注解.class) 标记。
- 目标注解(如
@Role)需用@Repeatable(RoleContainer.class)声明其容器 - 容器注解(如
@RoleContainer)必须只有一个 value 字段,类型为Role[] - 两个注解的
@Target和@Retention必须完全一致,否则编译报错
标准写法示例
以下是一个完整可用的例子:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(RoleContainer.class)
public @interface Role {
String value();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RoleContainer {
Role[] value();
}
这样定义后,就可以在类上直接写多个 @Role:
@Role("admin")
@Role("editor")
@Role("viewer")
public class User { }
运行时读取多个重复注解
反射 API 自动处理重复注解的获取逻辑。调用 getAnnotationsByType() 即可直接拿到所有 @Role 实例,无需手动解析容器:
-
clazz.getAnnotationsByType(Role.class)返回Role[],包含全部三个注解实例 -
clazz.getAnnotation(RoleContainer.class)也能获取容器,但一般不推荐直接用 - 注意不要用
getAnnotation(Role.class),它只返回第一个(或 null),不支持重复
常见错误与注意事项
容易出错的地方集中在元注解一致性与容器结构上:
- 容器注解的
value()方法返回类型必须是目标注解的数组,不能是其他名字或类型 - 两个注解的
@Target、@Retention、@Documented等元注解必须严格一致 - 容器注解不能有除
value()外的其他元素,否则编译失败 - IDE 或构建工具(如 Maven 编译器插件)版本过低可能不识别
@Repeatable,确保使用 JDK 8+ 且 source/target 设为 1.8
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











