Java自定义注解配合APT可在编译期生成代码,需定义SOURCE保留策略的注解、继承AbstractProcessor编写处理器、通过Filer生成文件,并正确注册处理器以避免循环和类型误判。

Java 中自定义注解配合 APT(Annotation Processing Tool)可以在编译期自动生成代码,核心是通过编写注解处理器(AbstractProcessor),在 javac 编译过程中扫描并处理特定注解,然后用 Filer 生成新的 Java 文件或资源文件。
定义自定义注解
注解需声明保留策略为 RetentionPolicy.SOURCE(仅保留在源码阶段),且必须指定 @Target(如 ElementType.TYPE、ElementType.FIELD 等):
- 使用
@Retention(RetentionPolicy.SOURCE)避免运行时加载开销 - 加上
@Target({ElementType.TYPE, ElementType.FIELD})明确可标注位置 - 若需传递配置,可用
String value() default ""或Class<?>[] types() default {}等属性
编写注解处理器
继承 AbstractProcessor,重写 process() 方法,通过 RoundEnvironment 获取被注解的元素:
- 在
init()中获取Messager(日志)、Filer(生成文件)、Elements(解析元素)等工具 -
process()中调用roundEnv.getElementsAnnotatedWith(YourAnnotation.class)拿到所有匹配元素 - 对每个
Element,用element.getSimpleName()、element.getEnclosedElements()等提取信息 - 用
filer.createSourceFile()创建 .java 文件,并用Writer写入内容(推荐结合 JavaPoet 或纯字符串拼接)
注册和打包处理器
让编译器识别你的处理器,有两种方式:
立即学习“Java免费学习笔记(深入)”;
- 在
resources/META-INF/services/javax.annotation.processing.Processor文件中写入处理器全限定类名(如com.example.MyProcessor) - 使用
@AutoService(Processor.class)(需引入auto-service库,自动注册) - 将处理器项目打成 jar 包,编译时通过
-processorpath指定路径,或 Maven 中配置maven-compiler-plugin的annotationProcessorPaths
注意事项与常见问题
APT 运行在编译期,不参与运行逻辑,但容易因误操作导致编译失败或无限循环:
- 不要在
process()中修改已有源文件,只能生成新文件 - 避免在一次 round 中生成又立即被本 processor 处理的注解(否则可能触发下一轮 processing,造成循环)
- 类型信息受限:不能直接用
instanceof判断泛型类型,需用Types.isSameType()或getKind() == ElementKind.CLASS等 API - 调试困难:可在
Messager中用warning()或error()输出提示,配合 IDE 的 annotation processor 设置启用 verbose 日志


















