Java的编译期是一个模糊的概念,需要具体分析。
- 将 *.java文件转为 *.class的过程称为编译器的前端(前端编译)。例如:JDK的javac编译器。
- 把字节码( *.class文件) 转变为 本地机器码 的过程称为Java虚拟机的即时编译运行期(JIT编译器,Just In Time)。例如:HotSpot虚拟机的C1、C2编译器。
- 使用静态的提前编译器(AOT编译器,Ahead Of Time Compiler)直接把程序变异成与目标及其指令集相关的二进制代码的过程。例如:JDK的Jaotc。
一.前端编译与优化
Javac 这类编译器对代码的运行效率几乎没有任何优化措施,虚拟机设计团队把对性能的优化都放到了后端的即时编译器中,这样可以让那些不是由 Javac 产生的 class 文件(如 Groovy、Kotlin 等语言产生的 class 文件)也能享受到编译器优化带来的好处。但是 Javac 做了很多针对 Java 语言编码过程的优化措施来改善程序员的编码风格、提升编码效率。相当多新生的 Java 语法特性,都是靠编译器的「语法糖」来实现的,而不是依赖虚拟机的底层改进来支持。
Java 中即时编译器在运行期的优化过程对于程序运行来说更重要,而前端编译器在编译期的优化过程对于程序编码来说更加密切。
1.1 Javac 编译器
Javac 编译器的编译过程大致可分为 1个准备过程3个处理过程 :
- 初始化插入式注解处理器
- 解析与填充符号表;
- 插入式注解处理器的注解处理;
- 分析与字节码生成。
这 3 个步骤之间的关系如下图所示:
解析与填充符号表