@repeatable 注解需配对容器注解,后者必须与被重复注解具有相同 @target 和 @retention,且 value() 方法返回该注解类型数组;运行时须用 getannotationsbytype() 获取,而非 getannotation()。

Java 8 引入的 @Repeatable 不是“绕开限制”,而是通过编译器自动封装 + 反射语义增强,让重复标注写起来自然、运行时拿得准确。
可重复注解必须配对容器
单有 @Repeatable 注解本身不够,它必须指向一个合法的容器注解。这个容器不是可选配件,而是强制要求:
- 容器注解的
@Target和@Retention必须与被重复注解完全一致(比如都是ElementType.METHOD和RetentionPolicy.RUNTIME) - 容器中必须声明一个
value()方法,返回类型严格为该重复注解类型的数组(如Role[]) - 容器注解自身不能加
@Repeatable,也不允许嵌套其他容器
写法上直接叠加,不包不套
定义好后,你就能在方法或类上连续写多个相同注解,无需手动包裹数组:
@IdempotentStrategy(value = "CREATE", key = "#id")
@IdempotentStrategy(value = "UPDATE", key = "#orderNo")
public void handle(Order order) { ... }
编译器会自动把这两行聚合成一个 @IdempotentStrategies({@IdempotentStrategy(...), @IdempotentStrategy(...)}),但你完全不用写、也不用看到它。
运行时必须用对反射方法
字节码里只存容器注解,原始注解不“直接存在”。所以:
-
method.getAnnotation(IdempotentStrategy.class)→ 返回null(查不到) -
method.getAnnotationsByType(IdempotentStrategy.class)→ 正确返回两个实例组成的数组 -
method.getAnnotation(IdempotentStrategies.class)虽能拿到,但需手动调.value()解包,多一步且易漏处理
常见错误和避坑点
很多问题其实卡在细节上:
- 容器注解没加
@Retention(RetentionPolicy.RUNTIME)→ 运行时反射拿不到任何内容 - 容器的
@Target比重复注解范围小(比如重复注解标在方法上,容器却只标了TYPE)→ 编译失败 - 容器中
value()方法返回类型写成List<role></role>或Role...→ 编译报错,必须是Role[] - 误以为
@Repeatable支持任意注解——它只对自定义注解生效,JDK 自带注解(如@Override)不可重复
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











