以下介绍Sun JDK源码编译机制,也就是javac将Java文件编译成class文件的过程
1. 词法解析
将代码字符串转换成Token流(比如哪一些是定义的关键字 int if for等 ,语法结束的分隔符 ; {} ()等,其实就是将代码字符串转换为接下来语法分析的最小单位字符序列)。
结果:得到Token流
2. 语法分析
根据词法分析中的Token的一些组合是否符合语法规范(词与词的组合是否符合语法规范)比如if语句后面有没有布尔类型的表达式
结果:生成一个符合Java语言规范的抽象语法树
3. 将符号输入到符号表
通常包括:确定类的超类型和接口、根据需要添加默认构造函数、将类中出现的符号输入到自身的符号表中(符号包括定义数据或方法名的命名字符,
int a ; void func()
)
4. 处理注解
根据注解生成附加的代码或做一些特殊的检查(注意对注解的处理会再次进入1、2、3)
5. 语义分析
进行一系列的语义分析,包括把一些难懂的语法解析成简单的语法
- 将语法树中的名字、表达式等元素与变量、方法、类型等联系到一起
- 检查:变量使用前是否声明、类型匹配、所有checked exception都捕获或抛出等
- 解除语法糖:泛型类型擦除、自动拆装箱、foreach、自动类型转换、子串常量合并
结果:生成一颗更接近目标语言规则的抽象语法树
6. 生成class文件
- 将实例成员初始化器收集到实例构造器中(对象),将静态成员初始化器收集到<clinit>();中(class initialize 类)
- 接着将抽象语法树生成字节码,采用的方式为后序遍历,并进行少量的代码转换(如String相加转变为StringBuilder操作)
- 生成class文件