java的编译器其实有三种,一种是前端编译器,负责把*.java文件转变为*.class文件.一种是后端运行期编译器,负责把字节码转变为本地机器码.了最后一种是静态提前编译器,直接把*.java文件编译成本地机器码.

下面先说前端编译器Javac编译器,大家最熟悉的过程,运行程序之前都会先编译代码.

Javac编译器不像HotSpot虚拟机那样使用c++语言实现,它是由java语言编写的程序.这类编译器对代码的运行效率几乎没有任何优化措施,对性能的优化都在后端编译器中.

编译过程大致分为:

1,解析与填充符号表

   1.1:解析包括词法分析,语法分析

        1.1.1词法分析

        是将源代码的字符流转变为标记(Token)集合,单个字符是程序编写过程的最小元素,而标记则是编译过程的最小元素,关键字,变量名,字面量,运算符都可以是标记,

        如"int a=b+2"这句话包含了6个标记,分别是int,a,=,b,+,2,虽然关键字int是3个字符组成,但是它是一个Token,不可再拆分.

        1.1.2语法分析

        是根据Token序列构造抽象语法树的过程.

   1.2填充符号表

待处理列表,包含了每一个编译单元的抽象语法树的顶级节点以及package-info.java的顶级节点.

2,插入式注解处理器的注解处理

Java1.5之后,java提供了注解的支持,插入式注解处理器在编译期间对注解进行处理,可以读取,修改,添加抽象语法树的任意元素.如果语法树被修改了,编译器会回到解析及填充符号表的过程,直到注解处理器都没有再对语法树进行修改为止,每一次循环称为一个Round.

3,语义分析与字节码生成

3.1语义分析的主要任务是对结构上正确的源程序进行上下文有关性质的审查.

    3.1.1标注检查

    检查的内容包括诸如变量使用前是否已被声明,变量与赋值之间的数据类型是否匹配等.

    3.1.2数据及控制流分析

    检查诸如程序局部变量在使用前是否有赋值,方法的每条路径是否都有返回值,是否所有的受检查异常都被正确处理了等问题.

3.2字节码生成

这是javac编译过程的最后一个阶段.不仅仅将前面各个步骤生成的信息转化成字节码写到磁盘中,还进行了少量的代码添加和转换工作.

完成了对语法树的遍历和调整之后,就会把填充了所有所需信息的符号表交给ClassWriter类,由这个类的writeClass()方法输出字节码,生成最终的Class文件.