Java元注解包括@Target(限定作用位置)、@Retention(控制生命周期)、@Documented(纳入Javadoc)、@Inherited(支持类继承传播)和@Repeatable(允许重复声明),共同规范注解的使用范围、可见性与语义表达。

Java注解本身是元数据的载体,而元注解则是控制这些元数据“如何存在、在哪存在、被谁看见”的核心规则。它们共同构成了一套轻量但严谨的声明式架构,不改变代码逻辑,却深刻影响编译、文档、反射和框架行为。
@Target:定义注解的“作用域边界”
它决定一个注解能合法出现在哪些程序元素上,是类型安全的第一道防线。没有@Target约束的自定义注解默认可加在任意位置,容易引发误用。
- 常用目标值包括:TYPE(类/接口/枚举)、METHOD(方法)、FIELD(字段)、PARAMETER(形参)、TYPE_USE(泛型类型引用,如List<@NonNull String>)
- 支持组合写法,例如
@Target({METHOD, FIELD, PARAMETER}),明确限定多处可用 - 若注解仅用于修饰其他注解(即作为元注解自身),应指定
ElementType.ANNOTATION_TYPE
@Retention:控制注解的“生命周期可见性”
它决定了注解信息存活到哪个阶段,直接关系到能否通过反射读取——这是运行时处理(如Spring、JUnit)的前提。
- SOURCE:只保留在源码中,编译后即丢弃(如 Lombok 的 @Data)
- CLASS:写入 .class 文件,但 JVM 加载时不进内存(默认策略,适用于字节码增强工具)
-
RUNTIME:完整保留至运行时,可通过
getAnnotation()获取(绝大多数框架注解都需此策略)
@Documented 与 @Inherited:扩展注解的“传播能力”
这两个元注解不改变功能逻辑,而是增强语义表达和继承行为。
立即学习“Java免费学习笔记(深入)”;
-
@Documented:让该注解出现在生成的 Javadoc 中,提升 API 文档可读性。比如自定义的
@ApiNote加上它,调用方看文档就能看到说明 -
@Inherited:仅对类级别注解生效,且只作用于 子类继承父类 场景(不适用于接口实现或方法重写)。例如
@Entity若标记为 @Inherited,则子类自动被视为实体,无需重复标注
@Repeatable:解决“同类语义多次声明”的表达瓶颈
Java 8 前,同一位置不能重复使用相同注解;@Repeatable 打破了这一限制,使语义更自然。
- 必须配对使用:先定义一个“容器注解”(如
@Schedules),再在目标注解上声明@Repeatable(Schedules.class) - 使用时可叠加多个,如
@Schedule(cron="0 0 * * *") @Schedule(cron="0 30 * * *") - 反射获取时,需调用
getAnnotationsByType(Schedule.class),而非getAnnotation()


















