关于注解处理器处理自生成无注解文件及编译警告重复输出的疑问
关于注解处理器处理自生成无注解文件及编译警告重复输出的疑问
嘿,这个场景我之前调试注解处理器时也碰到过,给你拆解一下问题:
为什么处理器p0会在Round 2被调用?
你的猜测完全正确!Java注解处理器的规范里有个明确规则:只要一个处理器在某一轮被触发执行过(哪怕只是因为它支持的注解存在),后续每一轮处理(包括最后的收尾轮)都会调用它,不管当前轮有没有它关心的注解。
这么设计是因为有些处理器可能需要跨轮次做后续工作——比如跟踪生成的代码、汇总数据,或者清理临时资源,哪怕新生成的代码没有注解,处理器也可能需要参与其中。所以哪怕你生成的FooBecauseOfX完全没注解,只要p0已经在Round1执行过,它就会被自动带入后续所有轮次。
怎么避免编译警告重复三次?
这个重复警告的根源是编译器在每一轮处理时,都会对当前所有存在的源文件做语法检查和lint分析:
- Round1结束时生成
FooBecauseOfX,编译器第一次检查它并输出警告; - Round2处理这个新生成的类时,编译器会再次扫描验证它,输出第二次警告;
- Round3作为收尾轮,部分编译器实现会做一次全局最终检查,导致第三次警告。
解决方法有两个方向:
- 从根源消除警告:既然警告是因为隐式构造方法,那在生成
FooBecauseOfX时,手动添加一个显式的空构造方法就行:
package foo; public class FooBecauseOfX { public FooBecauseOfX() {} // 显式构造,消除警告 }
这是最彻底的办法,一劳永逸。
2. 针对性禁用警告:如果你不想修改生成的代码,可以通过编译器参数针对生成代码的目录或包禁用特定警告。比如用javac的话,可以添加-Xlint:-missing-explicit-ctor(具体参数可能因编译器版本略有不同),或者把生成的代码目录标记为“无需lint检查”的目录。
另外补充一句:Round3的调用是正常的收尾流程,所有参与过处理的处理器都会被调用一次,此时roundEnvironment.processingOver()返回true,你可以在这个阶段做一些处理器的收尾工作(比如释放资源、输出最终报告等)。
备注:内容来源于stack exchange,提问作者Laird Nelson
相关产品推荐
相关产品推荐

