java注解生命周期由@retention控制,取值为retentionpolicy.source(仅源码,编译丢弃)、class(默认,存于字节码但反射不可见)、runtime(运行时可通过反射获取)。

Java 中注解的生命周期由 @Retention 元注解控制,它通过 RetentionPolicy 枚举指定注解在哪个阶段还“有效”。一共只有三个取值:SOURCE、CLASS、RUNTIME,各自对应不同阶段的可见性和用途。
RetentionPolicy.SOURCE:只活在源码里
这类注解仅保留在 .java 源文件中,javac 编译完成后就彻底丢弃,不会出现在 .class 文件里,运行时更无从谈起。
- 编译器能识别并据此做检查(比如
@Override就是 SOURCE 级别) - 不能被反射读取,也不能被字节码工具(如 ASM)处理
- 适合纯开发期辅助,比如标记临时 TODO、生成 javadoc 的自定义标签
RetentionPolicy.CLASS:停在字节码,进不了运行时
注解会写入 .class 文件,但 JVM 加载类时不会将其加载进内存,所以反射 API 获取不到它。
- 这是 默认策略 —— 如果你没显式写
@Retention,就按 CLASS 处理 - 构建期工具(如 APT、某些 Lombok 插件、字节码增强框架)可以读取和修改它
- 对运行时逻辑完全透明,不增加反射开销
RetentionPolicy.RUNTIME:一路带到运行时
注解不仅保留在 .class 文件中,还会被 JVM 加载到运行时内存,可通过 Class.getAnnotation() 等反射方法动态获取。
- Spring 的
@Autowired、JUnit 的@Test、Jackson 的@JsonIgnore都依赖这个级别 - 是实现框架自动化行为(如依赖注入、权限校验、序列化控制)的基础
- 带来一定反射成本,非必要不滥用
选哪个,关键看你想让注解在哪起作用:编译检查选 SOURCE,构建期处理选 CLASS,运行时动态决策选 RUNTIME。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











