javac是JDK默认且最稳的Java编译器,语法兼容性高、字节码行为可预测、CI/CD零适配;ECJ仅适合Eclipse开发阶段增量编译,发布必须用javac;IntelliJ底层仍调用javac;GCJ已淘汰。

javac 是默认且最稳的选择,别轻易换
绝大多数 Java 项目实际用的都是 javac——它不是“一种可选编译器”,而是 JDK 自带的、被所有构建工具(Maven/Gradle)和 IDE 默认调用的底层编译器。它的核心价值在于:**语法兼容性无争议、字节码行为可预测、CI/CD 流水线零适配成本**。
实操建议:
本文档主要讲述的是Android游戏开发之旅;今天Android123开始新的Android游戏开发之旅系列,主要从控制方法(按键、轨迹球、触屏、重力感应、摄像头、话筒气流、光线亮度)、图形View(高效绘图技术如双缓冲)、音效(游戏音乐)以及最后的OpenGL ES(Java层)和NDK的OpenGL和J2ME游戏移植到Android方法,当然还有一些游戏实现惯用方法,比如地图编辑器,在Android OpenGL如何使用MD2文件,个部分讲述下Android游戏开发的过程最终实现一个比较完整的游戏引擎
- 你在命令行敲
javac -version看到的版本,就是你当前 JDK 的语言支持上限(比如输出javac 21.0.2,说明能完整支持 Java 21 的record、sealed、虚拟线程等特性) - 想让新 JDK 编译出老 JVM 能跑的字节码?必须加
-source和-target(或--release),例如:javac --release 8 MyService.java,否则默认生成的是当前 JDK 版本的字节码,可能在旧环境报java.lang.UnsupportedClassVersionError - 别因为 Eclipse 或 IDEA 里“编译快”就以为它们用了别的编译器——IntelliJ 默认仍调
javac;Eclipse 的 ECJ 虽然快,但若你最终要打 jar 包上线,务必用javac过一遍,避免“IDE 能跑,生产炸了”的兼容性翻车
ECJ(Eclipse 编译器)适合大型项目快速迭代,但慎用于发布构建
ECJ 是 Eclipse IDE 内置的 org.eclipse.jdt.core.compiler,最大特点是**不依赖完整 classpath 就能增量编译**,甚至允许部分类编译失败时继续编译其他类——这在开发阶段很友好,但在构建产物时就是隐患。
常见错误现象:
立即学习“Java免费学习笔记(深入)”;
- 在 Eclipse 里改完代码自动编译成功,但用 Maven 执行
mvn compile却报错:ECJ 宽容了未初始化的 final 字段、泛型擦除冲突等 javac 会严格拦截的问题 - 用 ECJ 编译出的
.class文件,在某些 JVM 上运行时报VerifyError:ECJ 对字节码校验比 javac 松,生成的指令可能绕过 JVM 的验证逻辑
实操建议:
- 只在 Eclipse IDE 内启用 ECJ 做日常开发;导出可部署包时,强制 Maven/Gradle 使用
javac(默认即如此,无需额外配置) - 若非得在命令行用 ECJ(比如嵌入式构建脚本),需下载
ecj.jar并显式调用:java -jar ecj.jar -source 17 -target 17 MyCode.java,注意它不读CLASSPATH环境变量,所有依赖必须用-cp显式传入
IntelliJ 的“编译器”本质是 javac + 智能缓存,不是独立编译器
很多人误以为 IntelliJ 有自己专属的 Java 编译器,其实它底层仍是调用 javac,只是通过 JPS(Java Project System) 构建服务做了两件事:把源码变更映射到最小编译单元(.java → .class)、把编译结果缓存在内存中供热更新(HotSwap)或调试器即时加载。
性能与兼容性影响:
- 修改一个方法体,IntelliJ 可能几毫秒内完成重编译并 reload 到正在运行的 JVM 中;而纯
javac命令每次都要启动新进程、扫描整个 classpath,慢一个数量级 - 它不会改变
javac的语义——你看到的语法错误提示、Lambda 推导、类型检查,全来自标准javac,所以不用担心“IDE 不报错,打包就挂” - 唯一要注意的是:IntelliJ 的 Build → Build Project 默认不触发
javac -Xlint:all这类警告检查,如需严格质量门禁,得在 Maven 的maven-compiler-plugin里显式配置
GCJ 已淘汰,别再考虑它
gcj(GNU Compiler for Java)曾试图把 Java 源码直接编译成机器码,绕过 JVM。但它在 Java 5 之后就停止维护,**不支持泛型、注解、枚举、NIO、任何 JSR 规范,更别说 Java 8+ 的流式 API 和模块系统**。2026 年还在提 GCJ,就像在问“IE6 怎么加速网页”——方向错了。
如果你真需要“无 JVM 运行”,现实路径只有两条:
- 用 GraalVM 的
native-image工具,基于标准javac编译出的字节码生成原生可执行文件(支持 Java 17+,需处理反射/动态代理等限制) - 用 JLink + JPackage 打包精简 JDK + 应用 jar,生成带 JVM 的自包含应用(更轻量、更主流、无兼容风险)
ECJ 和 IntelliJ 的编译加速机制都建立在“信任 javac 语义”的前提下;真正要动编译器层面,只有 javac 的插件(如 ErrorProne、Checker Framework)或 GraalVM 这类现代替代方案值得投入时间。其他所谓“编译器”,不过是包装或缓存层而已。









