java中@repeatable注解必须配套容器注解才能生效:目标注解需标注@repeatable(容器.class),容器注解须具相同@target和@retention,且value()方法返回目标注解数组;运行时须用getannotationsbytype()获取全部实例。

Java 中通过 @Repeatable 注解,可以让自定义注解在同一个声明位置被多次使用——否则编译器会报错“重复的注解”。关键在于:必须配套定义一个“容器注解”,并让重复注解声明其容器类型。
1. 定义可重复的注解(目标注解)
用 @Repeatable 标注你的自定义注解,并指定其容器注解的 Class。注意:该注解本身必须是 @Retention 和 @Target 有效的。
- 容器注解的返回类型必须是目标注解类型的数组
- 容器注解的
value()方法必须返回目标注解数组 - 容器注解也需声明相同的
@Retention和@Target
2. 编写对应的容器注解
容器注解不是自动产生的,必须手动编写。它的名字可以任意,但习惯以 “List” 结尾(如 RolesList)。它只起“包装”作用,不承载业务逻辑。
例如,定义一个 @Role 注解用于标记用户角色:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
@Repeatable(RolesList.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Role {
String value();
}
对应容器注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RolesList {
Role[] value();
}
3. 在代码中重复使用该注解
现在可以在同一方法上多次标注 @Role:
public class UserService {
@Role("ADMIN")
@Role("EDITOR")
@Role("VIEWER")
public void updateUser() { }
}
运行时可通过反射获取全部 @Role 实例:
Method method = UserService.class.getMethod("updateUser");
Role[] roles = method.getAnnotationsByType(Role.class); // 直接拿到数组,无需手动解析容器
// roles.length == 3,顺序与声明一致
注意:getAnnotation(Role.class) 会返回 null(因为单值获取不适用),必须用 getAnnotationsByType。
4. 注意事项和常见坑
-
@Repeatable是 Java 8 引入的,低版本不支持 - 容器注解不能省略;即使只用一次
@Role,底层仍会封装成容器形式,但反射 API 已透明处理 - 两个注解的
@Retention和@Target必须完全一致,否则编译失败 - IDE 或 javac 对重复注解的支持依赖正确配置,确保项目源码级别 ≥ 8
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










