1、编译期
定义:把*.java文件转换成*.class文件的过程。
虚拟机设计团队把对性能的优化集中到了后端的即时编译器中,这样可以让那些不是由Javac产生的Class文件(如JRuby、Groovy等语言的Class文件)也同样能享受到编译器优化所带来的好处。
可以说,Java中即时编译器在运行期的优化过程对于程序运行来说更重要,而前端编译器在编译期的优化过程对于程序编译来说关系更加密切(如编译器的“语法糖”)。
2、常量折叠 P265
形如int a = 1 + 2;
在编译期间进行了常量折叠,所以在代码里面直接定义“a=1+2”比起直接定义“a = 3”,并不会增加程序运行期哪怕仅仅一个CPU指令的运算量。
3、一个方法的参数和局部变量定义是否使用final修饰符,对运行期是没有影响的(二者的Class文件一模一样),变量的不变性仅仅由编译器在编译期间保证。P267
4、字节码生成:
字节码生成是Javac编译过程的最后一个阶段,实例构造器<init>()方法和类构造器<clinit>()方法就是此阶段添加到语法树中的。期间编译器还会进行少量的代码添加和转换工作。
编译器会把语句块(对实例构造器而言是“{}”块,对于类构造器而言是“static{}”块、变量初始化(实例变量和类变量)、调用父类的实例构造器(仅仅是实例构造器, <clinit>()方法中无须调用父类的<clinit>()方法,虚拟机自动保证父类构造器的执行)等操作收敛到 <init>()和<clinit>()方法之中,并且保证一定是按先执行父类的实例构造器,然后初始化变量,最后执行语句块的顺序进行。
此外,还有一些优化的逻辑,如把字符串的加操作替换为StringBuffer和StringBuilder(取决于目标代码的版本是否大于或等于JDK1.5)的append()操作。
5、语法糖
(1)泛型
重载的方法具有不同的特征签名,而特征签名并不包括返回值。但Class文件格式中,只要描述符不是完全一致的两上方法就可以共存,即两个方法如果有相同的名称和特征签名,但返回值不同,那它们也可以合法地共存于一个Class文件之中。P271