java注解处理器在编译期(javac阶段)运行,通过processor入口、roundenvironment查找元素、filer生成新.java文件,实现零运行时开销的代码生成。

Java 注解处理器(Annotation Processor)生成代码这类面试题,不是靠死记硬背,而是靠理解流程+记住关键接口+熟悉典型场景。背代码片段容易忘,但掌握“谁在什么时候干了什么”就稳了。
下面分三块讲清楚,直接对应高频面试问法:
注解处理器运行在哪一阶段?
- 编译期(javac 阶段),不是运行时,也不是类加载时。
- 它在
.java编译成.class之前介入,能读取源码中的注解,还能生成新的.java文件(比如XXX$$ViewBinder.java)。 - 关键点:它不修改原有类,只“旁观+产出”,所以不影响原有编译逻辑。
核心要记住的三个接口
不用全背方法签名,但得知道它们各管啥:
-
Processor:主入口,必须实现process()方法,是整个处理逻辑的起点。 -
RoundEnvironment:每次处理轮次的上下文,提供getElementsAnnotatedWith(YourAnnotation.class)这类核心方法。 -
Filer:专门用来生成新源文件或资源文件,调用filer.createSourceFile("com.example.XXX")就能写出.java文件。
✅ 小技巧:把这三个词串起来想——
“Processor 启动 → 用 RoundEnvironment 找到带注解的元素 → 用 Filer 写出新代码”。
常见考法和一句话答法
面试官常问的,其实就这几类,照着答不卡壳:
-
Q:APT 和反射读注解,有什么区别?
- APT 在编译期生成代码,零运行时开销;反射在运行时读注解,有性能损耗、还依赖
@Retention(RUNTIME)。
- APT 在编译期生成代码,零运行时开销;反射在运行时读注解,有性能损耗、还依赖
-
Q:为什么 ButterKnife 不用反射了?
- A:早期用反射找
@BindView,慢且可能失败;后来改用 APT,在编译时生成绑定类,直接调用findViewById,安全又快。
- A:早期用反射找
-
Q:自定义注解处理器怎么注册?
- A:在
src/main/resources/META-INF/services/javax.annotation.processing.Processor文件里,写一行你 Processor 的全限定名,比如com.example.MyProcessor。
- A:在
-
Q:能举一个 APT 生成代码的例子吗?
- A:比如
@Route(path = "/user/detail"),APT 扫描所有被标记的方法,生成一个RouteTable类,里面用static块注册路径和目标 Activity,启动时直接查表跳转,不用反射。
- A:比如
不复杂但容易忽略:注解处理器本身不能依赖运行时类库(比如不能用 Spring 的 @Component),因为它跑在 javac 环境里,类路径很干净。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











