Java Compiler API 核心原理与应用场景
一、背景与定位
1. 诞生背景
在 Java 6(JSR 199) 之前,Java 的编译能力主要以两种形式存在:
- 命令行工具:
javac - IDE / 构建工具内部实现(如 Ant、IDEA、Eclipse 的编译器)
Java Compiler API (JSR 199) 将 javac 能力标准化为可编程接口,位于 javax.tools 包。核心组件包括 ToolProvider、CompilationTask、JavaFileObject 等,支持源码编译、内存编译及错误诊断。该 API 是构建代码分析、动态执行、插件系统及 IDE 工具链的基础设施,与注解处理器(JSR 269)深度集成。相比 Roslyn,其侧重编译控制而非平台化操作,适用于静态检查、规则引擎及热加载场景,但需注意模块化配置复杂度及并发缓存问题。
在 Java 6(JSR 199) 之前,Java 的编译能力主要以两种形式存在:
javac这些方式存在明显局限:
Java Compiler API(JSR 199) 的目标是:
将
javac的核心能力以 标准化、可编程 API 的形式暴露出来。
Java Compiler API 主要位于:
javax.tools
其整体结构可以理解为一个 可嵌入式编译器框架。


| 接口 / 类 | 作用 |
|---|---|
JavaCompiler | 编译器主入口 |
ToolProvider | 获取系统编译器 |
CompilationTask | 一次编译任务 |
JavaFileObject | 抽象的'源码/字节码文件' |
JavaFileManager | 文件管理与输出控制 |
StandardJavaFileManager | 默认文件系统实现 |
Diagnostic / DiagnosticCollector | 编译错误、警告信息 |
FileObject | 更通用的文件抽象 |
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
nulljavac 的程序化入口public interface JavaFileObject extends FileObject
它抽象了:
.java 源码.class 字节码SimpleJavaFileObjectStandardJavaFileManager 内部实现这也是 '内存编译''动态代码生成' 的基础。
负责:
.class)的输出位置StandardJavaFileManager fm = compiler.getStandardFileManager(diagnostics, null, null);
JavaFileManager.class 输出到:
JavaCompiler.CompilationTask task = compiler.getTask(writer, fileManager, diagnostics, options, classes, compilationUnits);
| 参数 | 含义 |
|---|---|
writer | 编译器输出(stdout/stderr) |
fileManager | 文件管理 |
diagnostics | 错误收集 |
options | -classpath、-source 等 |
classes | 注解处理目标类 |
compilationUnits | 待编译源码 |
for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
System.out.println(d.getKind());
System.out.println(d.getMessage(null));
}
可获取:
这使得 IDE、代码分析器、在线判题系统 成为可能。
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
Iterable<? extends JavaFileObject> units = fileManager.getJavaFileObjectsFromStrings(List.of("HelloWorld.java"));
boolean success = compiler.getTask(null, fileManager, diagnostics, null, null, units).call();
核心思路:
SimpleJavaFileObjectString 存源码ByteArrayOutputStream 存 .class这是 脚本引擎 / DSL / 规则引擎 的基础能力。
Java Compiler API 与 注解处理器 深度集成:
javac ├─ Parse ├─ Enter ├─ Annotation Processing ← APT ├─ Attr ├─ Flow ├─ Desugar └─ Generate
你可以通过 Compiler API 显式启用 / 控制注解处理器。
| 维度 | Java Compiler API | Roslyn |
|---|---|---|
| AST 可操作性 | 中等 | 极强 |
| API 现代性 | 一般 | 非常好 |
| 编译即服务 | 支持 | 原生支持 |
| 增量编译 | 弱 | 强 |
| 语法树改写 | 困难 | 一等公民 |
Java Compiler API 偏'编译控制'
Roslyn 偏'编译平台'
Java Compiler API 是'把 javac 变成库'的官方标准方案,是构建 Java 代码分析、动态编译、DSL、工具链与平台级能力的基础设施。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online