Java之所以能够解决程序的安全性、跨平台移植性问题,主要原因就是Java源代码的编译结果并不是本地指令,而是字节码文件。

开发人员在使用Java语言编写一个Java程序的时候需要遵守Java语法规范,而降源代码编译为字节码的时候有需要符合JVM规范,

简单来说,前端编译器的主要任务就是负责将符合Java语法贵方的Java代码转换为符合JVM规范的字节码文件。JVM并不会与Java

语言“终生绑定”,任何语言编写的程序都可以运行在JVM中,前提是源码的编译结果满足并包含Java虚拟机的内部指令集、符号表、

以及其他的辅助信息,他就是一个有效的字节码文件,就能被虚拟机所识别并装载运行。

编译器简介:Javac.exe:

Java前端编译器全量编译;

负责将符合Java语法规范的Java代码转换为符合JVM规范的字节码文件;

前端编译器并不会直接涉及编译优化等技术,而是将具体细节移交给HotSpot的JIT编译器负责。

ECJ:

Eclipse缺省前端编译器,增量编译,比javac更高效;

编译的字节码文件与javac一样。

编译原理:

词法解析:将java源码中的关键字和标识符转换为符合java语法规范的Token序列,

然后按照指定的排序规则进行匹配校验。

语法解析:将词法解析后的Token序列整合为一颗结构化的抽象语法树。

语义解析:将抽象语法树补充得更加完善。

生成字节码。

java编译器工作流程 java编译器原理_编译器

词法解析:主要将Java源码中的关键字和标示符等内容转换为符合Java语法规范的Token序列,然后按照指定的顺序规则进行匹配校验,

以便为后续的语法解析步骤做准备。Scanner类:按照单个字符的方式读取Java源文件中的关键字和标示符;

com.sun.tools.javac.parser.JavacParser类:将Scanner类读取的字符转换为符合Java语法规范的Token序列,

该类的对象实例由ParserFactory工厂负责创建;

JavacParser类的parseCompilationUnit()方法:由该方法负责调用Scanner类的nextToken()方法,

获取出Token后再按照指定的顺序规则进行匹配校验;

Token序列:一组对应源码字符集合的单词序列(一个枚举类型)。

词法解析器又是采用什么方式保存源码字符集合与Token之间的对应关系?

答:先将每一个字符集合都转换为一个对应的Name对象,然后再由com.sun.tools.javac.parser.Keywords类负责实际的Token转换任务。

Keywords类会将Token中的所有枚举常量全部都转换为Name对象,然后将其存储在Name对象的内部类Table中,

这样一来源码字符集合与Token之间的对应关系就成功构建起来了。

源码字符集合是如何转换成Token的?

答:当词法解析器需要将源码字符集合转换为Token时,就会通过Names类去调用Name类的fromChars()方法获取一个Name对象,

然后在调用Keywords类的key()方法时传入这个Name对象就可以成功获取出对应的Token,

这样一来词法解析器即可成功地将源码将字符集合转换为Token。

语法解析:词法解析的Token序列并不完善,只是一个对应的单个源码字符集合,此时语法解析的任务就是将这些零散的Token

按照指定的Java语法规范整合起来形成一个有机的整体。JCTree类:语法树中的每一个语法节点都会直接或间接地继承了JCTree,

与语法树中的每一个节点都保持着密不可分的关系。

parseCompilationUnit方法:

1.包含词法解析方法

2.包含语法解析方法

调用qualident() 解析package节点

调用importDeclaration() 解析import节点

调用classDeclarartion() 解析class节点

语意解析:为没有构造方法的类型添加缺省的无参构造方法;

检查任何类型的变量在使用前是否都已经经历过初始化;

检查变量类型是否与值匹配;

将String类型的常量进行合并处理;

检查代码中的所有操作语句是否可达;

异常检查;

解除Java语法糖。

生成字节码:com.sun.tools.javac.jvm.Gen类JVM的架构模型是基于栈的操作,所有操作都是出栈和入栈。

前4个字节:0xCAFEBABE --> magic

5,6字节:次编译版本号

7,8字节:主编译版本号

一组8字节(64位)单位的字节流组成了一个完整的字节码文件。

GCJ编译器:将java源码直接编译为本地机器指令。JavaInJava:寄生在宿主机运行字节码文件。

需要前端编译器编译字节码文件;

宿主机装载字节码文件到其内部;

没有JIT编译器,只靠解释器,所以效率低下。

Maxine:

内置JIT编译器;

编译结果为本地指令;

不依赖宿主机独立运行。