Java元注解共五个:@Target限定作用位置,@Retention控制生命周期(SOURCE/CLASS/RUNTIME),@Documented使注解出现在Javadoc中,@Inherited支持类级注解继承,@Repeatable实现同一位置重复使用注解。

要真正用好自定义注解,必须先吃透元注解——它们不是可选项,而是定义注解行为的强制约束条件。没有正确配置元注解,注解就无法在预期位置生效,也无法在需要的阶段被读取。
@Target:明确注解能贴在哪
它规定注解可以标注的程序元素类型,不设或设错会导致编译报错“Invalid target”。
- 常用值包括:TYPE(类、接口、枚举)、METHOD(方法)、FIELD(字段)、PARAMETER(参数)、CONSTRUCTOR(构造器)
- 支持组合写法:@Target({ElementType.TYPE, ElementType.METHOD}) 表示既可用于类也可用于方法
- 若想限制仅用于方法,必须写 @Target(ElementType.METHOD),不能省略
@Retention:决定注解活到什么时候
这是运行时能否通过反射获取注解的关键。多数业务场景(如AOP切面、权限校验)都依赖运行时注解,所以必须显式指定。
- SOURCE:只存在于源码,编译后消失 → 适合 Lombok 风格的编译期代码生成
- CLASS:保留在 .class 文件中,但 JVM 不加载 → 框架一般不用此级别
- RUNTIME:编译保留 + 运行时可反射读取 → 95% 的自定义注解需设为 RUNTIME
@Documented 和 @Inherited:增强可用性的小而关键项
这两个元注解不强制,但加了能让注解更“友好”。
立即学习“Java免费学习笔记(深入)”;
- @Documented:让注解出现在生成的 JavaDoc 中,方便团队查阅 API 文档时看到注解语义
- @Inherited:仅对类级注解有效,表示子类会自动继承父类上的该注解(注意:方法、字段不继承)
@Repeatable:解决“同一个地方贴多个同类标签”的需求
默认注解不可重复使用,比如不能在同一个方法上写两次 @Log。启用重复需两步:
- 定义一个容器注解(如
@Logs),其 value 属性类型为原注解数组 - 在原注解上声明 @Repeatable(Logs.class)
- 使用时可直接写多次
@Log("A") @Log("B"),反射读取时通过method.getAnnotationsByType(Log.class)


















