10.2 Javac编译器

10.2.1 Javac的源码与调试

下载

10.2.2 解析与填充符号表

  1. 词法、语法分析

    • 词法分析: 将源代码的字符流转变为标记(Token)集合的过程,单个字符是程序编写时的最小元素,但标记才是编译时的最小元素。关键字、变量名、字面量、运算符都可以作为标记,如“inta=b+2”标记是int、a、=、b、+、2。由com.sun.tools.javac.parser.Scanner类来实现。
    • 语法分析: 根据标记序列构造抽象语法树的过程,抽象语法树(Abstract Syntax Tree,AST)是一种用来描述程序代码语法结构的树形表示方式,抽象语法树的每一个节点都代表着程序代码中的一个语法结构(Syntax Construct),例如包、类型、修饰符、运算符、接口、返回值甚至连代码注释等都可以是一种特定的语法结构。由com.sun.tools.javac.parser.Parser类实现
  2. 填充符号表
    符号表(Symbol Table)是由一组符号地址和符号信息构成的数据结构。符号表中所登记的信息在编译的不同阶段都要被用到。譬如在语义分析的过程中,符号表所登记的内容将用于语义检查和产生中间代码,在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的直接依据。由com.sun.tools.javac.comp.Enter类实现,该过程的产出物是一个待处理列表,其中包含了每一个编译单元的抽象语法树的顶级节点,以及package-info.java的顶级节点

10.2.3 注解处理器

10.2.4 语义分析与字节码生成

语义分析的任务是对源程序进行上下文检查,譬如类型检查、控制流检查、数据流检查等

  1. 标注检查
    检查变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配等,还会顺便进行一个称为常量折叠(Constant Folding)的代码优化(例如int a = 1 + 2;优化为3).实现类是com.sun.tools.javac.comp.Attr类和com.sun.tools.javac.comp.Check类
  2. 数据及控制流分析
    对程序上下文逻辑更进一步的验证,检查程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了等.编译时期与类加载时校验范围有所区别,有一些校验项只有在编译期或运行期才能进行(例如final语义校验).由com.sun.tools.javac.comp.Flow类来完成
  3. 解语法糖
    由desugar()方法触发,在com.sun.tools.javac.comp.TransTypes类和com.sun.tools.javac.comp.Lower类中完成
  4. 字节码生成
    由com.sun.tools.javac.jvm.Gen类来完成。不仅是把前面各个步骤所生成的信息(语法树、符号表)转化成字节码指令 写到磁盘中,还进行了少量的代码添加和转换工作

10.3 Java语法糖的味道

10.3.1 泛型

10.3.2 自动装箱、拆箱与遍历循环

10.3.3 条件编译