javac编译器(笔记)

一、javac编译器

javac编译器本身就是由java语言编写的程序。

1.1 编译过程

SunJavac的代码来看,编译过程大致可以分为3个过程:

  • 解析与填充符号表过程。
  • 插入式注解处理器的注解处理过程。
  • 分析与字节码生成过程
    这里写图片描述

Javac编译动作的入口是com.sun.tools.javac.main.JavaCompiler类,上述3个过程的代码逻
辑集中在这个类的
compile()compile2()`方法中,整个编译最关键的处理就由下图中标注的8个方法来完成

javac编译器(笔记)_第1张图片


1.2 解析与填充符号表

解析由parseFiles()方法完成,解析步骤包括 词法分析和语法分析两个过程


1.2.1 词法分析

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

如“nt a=b+2这句代码包含了6个标记,分别是int、a、=、b、+、2,虽然关键字int由3个字符构成,但是它只是一个Token,不可再拆分。在Javac的源码中,词法分析过程由com.sun.tools.javac.parser.Scanner类来实现


1.2.2 填充符号表

enterTrees()方法完成;填充符号表的过程由com.sun.tools.javac.comp.Enter类实现


1.3 注解处理器

在Javac源码中,插入式注解处理器的初始化过程是在initPorcessAnnotations()方法中完成的,而它的执行过程则是在processAnnotations()方法中完成的,这个方法判断是否还有新的注解处理器需要执行,如果有的话,通过
com.sun.tools.javac.processing.JavacProcessingEnvironment类的doProcessing()方法生成一个
新的JavaCompiler对象对编译的后续步骤进行处理


1.4 语义分析与字节码生成

语法分析之后,编译器获得了程序代码的抽象语法树表示,语法树能表示一个结构正确的源程序的抽象,但无法保证源程序是符合逻辑的

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


Javac的编译过程中,语义分析过程分为标注检查以及数据及控制流分析两个步骤,分别由attribute()flow()方法完成。

1.4.1 标注检查

标注检查步骤检查的内容包括诸如变量使用前是否已被声明、变量与赋值之间的数据类型是否能够匹配等


1.4.2 数据及控制流分析

数据及控制流分析是对程序上下文逻辑更进一步的验证,它可以检查出诸如程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了等问题


1.4.3 解语法糖

在Javac的源码中,解语法糖的过程由desugar()方法触发,在com.sun.tools.javac.comp.TransTypes类和com.sun.tools.javac.comp.Lower类中完成


1.4.4 字节码生成

字节码生成是Javac编译过程的最后一个阶段,在Javac源码里面由com.sun.tools.javac.jvm.Gen类来完成。字节码生成阶段不仅仅是把前面各个步骤所生成的信息(语法树、符号表)转化成字节码写到磁盘中,编译器还进行了少量的代码添加和转换工作


完成了对语法树的遍历和调整之后,就会把填充了所有所需信息的符号表交给com.sun.tools.javac.jvm.ClassWriter类,由这个类的writeClass()方法输出字节码,生成最终的Class文件,到此为止整个编译过程宣告结束


参考

  1. Java 源代码编译成 Class 文件的过程分析
  2. 更加详细的内容,参考《深入理解java虚拟机》–周志明

你可能感兴趣的:(JVM,深入理解Java虚拟机)