@repeatable 的容器注解的 value 属性必须是对应子注解类型的一维数组且名称为 value,容器注解需 public、同包可见,不可再标记 @repeatable,否则编译报错。

在 Java 中,@Repeatable 的容器注解(container annotation)的 value 属性必须满足一个关键规范:它的返回类型必须是被标记为 @Repeatable 的那个注解类型的**一维数组**。
容器注解的 value 属性必须是子注解的一维数组
这是 Java 语言规范(JLS §9.6.3)明确要求的。例如,若定义了一个可重复注解 @Role,那么它的容器注解(如 @Roles)中必须声明一个名为 value 的元素,且其类型只能是 Role[]:
@Repeatable(Roles.class)
public @interface Role {
String value();
}
public @interface Roles {
Role[] value(); // ✅ 合法:返回类型是 Role[]
}
如果写成其他形式,编译器会直接报错:
-
Role value()—— 不是数组,非法 -
List<role> value()</role>或Role[][]—— 类型不匹配,非法 -
Role[] roles()—— 名字不是value,非法(名称也必须叫value)
容器注解必须与子注解在同一个作用域可见
容器注解需能被编译器在相同上下文中解析到。通常做法是将它与子注解放在同一包下,并确保访问级别为 public。如果容器注解不可见或不可访问,即使类型正确,也会导致编译失败或运行时无法解析重复注解。
容器注解本身不能是 @Repeatable
Java 不允许嵌套可重复:容器注解自身不能再标注 @Repeatable。否则会引发编译错误。这是因为容器的作用就是“收容”多个同类型注解,再让它可重复会导致语义混乱和实现复杂性问题。
运行时通过 getAnnotationsByType 获取重复注解
使用 getAnnotationsByType(Role.class) 时,JVM 会自动查找该元素上所有 @Role 实例,包括直接声明的以及通过 @Roles({@Role("a"), @Role("b")}) 集合声明的。这个机制依赖于容器注解严格遵循上述规范,否则反射 API 将无法正确展开。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











