@Retention(RetentionPolicy.SOURCE)注解仅保留在源码中,编译后即丢弃,不进入.class文件,因此无法被反射读取;其作用需依赖自定义注解处理器在编译期执行校验、代码生成等逻辑。

@Retention(RetentionPolicy.SOURCE) 表示该注解仅保留在源代码中,编译器处理完后就丢弃,不会写入 .class 文件,因此它无法在编译期“生效”为运行时可读取或参与逻辑判断的注解。它的“生效”,本质是被编译器(或配套的注解处理器)在编译阶段识别并执行特定动作——但这需要额外配合 注解处理器(Annotation Processor),而不是靠注解自身触发。
它不生效于反射或运行时
因为 SOURCE 级注解不会进入字节码,所以:
- 不能通过 Class.getDeclaredAnnotations() 获取
- 不能用 @Target(ElementType.TYPE) + 反射检查类上是否有该注解
- JVM 加载类时完全不知道它的存在
它只在编译期“起作用”的前提:必须有注解处理器
要让 @Retention(SOURCE) 发挥作用,你需要编写或引入一个 javax.annotation.processing.AnnotationProcessor 子类,并在 META-INF/services/javax.annotation.processing.Processor 中声明它。编译器(如 javac)在编译时会自动加载并运行这些处理器。
- 处理器通过 roundEnvironment.getElementsAnnotatedWith(...) 拿到被 SOURCE 注解标记的元素(如类、方法)
- 你可以在处理器里做校验(如禁止某方法加 @DeprecatedButNotYet)、生成辅助代码(如 Builder 类)、抛出 CompilationError
- 示例:Lombok 的 @Getter、@ToString 底层就是 SOURCE 注解 + 自定义注解处理器实现的
如何验证它确实在编译期起作用
简单验证方式:
立即学习“Java免费学习笔记(深入)”;
- 写一个 @Retention(SOURCE) 注解和对应 Processor,在 processor.process() 里 System.err.println("I'm running!")
- 用 javac -processorpath your-processor.jar -proc:only YourClass.java 编译
- 看到打印说明处理器被调用,注解被识别 —— 这就是它的“生效”
- 反编译生成的 .class 文件,确认该注解不存在
常见误区提醒
不要以为加了 @Retention(SOURCE) 就能自动触发任何逻辑:
- Java 编译器本身对绝大多数 SOURCE 注解无默认行为(除少数内置如 @Override、@SuppressWarnings)
- 没有注册 Processor,SOURCE 注解就只是个“注释”,编译器直接忽略
- IDE(如 IntelliJ)可能自带部分注解处理器支持,但实际编译仍需显式配置或依赖正确引入


















