源码编译

在上一篇中,我们了解了下jvm的基本结构,我们知道了,jvm是通过加载.class文件来进行后续工作的,所以在这之前 我们还是先来了解下从源码到字节码(.class文件)的基本过程: 和大多数编译器一样,java编译器将源码编译成字节码需要经过词法分析–>语法分析–>语义分析,这几个主要的步骤。

###词法分析,语法分析

在词法分析过程中,主要是将代码转化成

<token-name,attribute-value>

这样的token序列,紧接着将token序列字符流交由语法分析器进行 语法分析生成语法树,这两个步骤可以概括为分析过程,完成分析后进行输入到符号表的输入过程,而输入到符号表主要包括:确定类的超类型和接口,根据 需要添加默认构造器,将类中出现的符号输入类自身的符号表中等步骤。通过输入到符号表工作后,将进行注解(Annotation)处理, 对于JDK5.0后引入的这一特性,可以使用户自定义一些注解,来生成附加代码或者检查等,例如当通过使用Lombok通过一些例如@Getter注解, 在编译时将会处理这个注解自动生成get方法。完成注解处理后,将继续返回分析和输入到符号表,因为通过注解处理后又生成了新的 词法,当然也得进行分析并放入符号表。

###语义分析

完成了以上所有的语法分析后,最终进入语义分析步骤,语义分析是基于抽象语法树进行的,这个过程包括将语法树中的表达式,名字等 元素与变量,方法,类型等联系到一起;检查变量使用前是否已经声明;推导泛型方法的类型参数;解除语法糖;转化泛型; 检查确定性赋值,例如又返回值的方法必须确定有返回值;检查所有的checked exception都被捕获或者抛出;将含有语法糖的 语法树改为含有简单语言结构的语法树,如foreach循环,自动拆箱/装箱等。

###生成class文件

完成语义分析后,就进入到生成class文件的步骤了,该步骤首先将实例成员初始化器收集到构造器中,将静态成员初始化器收集为

<clinit>();

接着采用后续遍历语法树将抽象语法树生成字节码,最后进行少量的代码转换(其实这也是一些代码优化工作),比如将String相加转变为StringBuilder 操作;最后从符号表生成class文件。

小结

本篇简单介绍了从java源码编译生成字节码文件的过程,在下篇中将具体分析class文件。

  • 参考:分布式Java应用;编译原理

##文档信息