学习《深入了解Java虚拟机》有一段时间了,大概理解了Java从源代码编译到执行出结果的过程,也能明确的知道Java是半解释性语言。在执行源代码时,先通过Javac编译器对源代码进行词法分析、语法分析、生成抽象语法树、语义分析等,这部分操作是在Java虚拟机之外进行的,而解释器在虚拟机内部,所以Java程序的编译就是半独立的实现过程。

一、了解一下javac编译的详解过程

编译过程大致上分为三步:解析与填充符号表过程、插入式注解处理器的注解处理过程、分析与字节码生成过程。

(1)词法、语法分析

  词法分析是将源代码的字符流转变为标记(Token)集合,单个字符是程序编写过程的最小元素,而标记则是编译过程的最小元素,关键字、变量名、字面量、运算符都可以称为标记,如“int a = b + 2”这句代码包含了6个标记,不可拆分,分别为int、a、=、b、+、2,虽然关键字int由3个字符构成,但是它只是一个标记(Token),不可再拆分。

  语法分析是根据Token序列构成抽象语法树的过程,抽象语法树(Abstract Syntax Tree)是一种用来描述程序代码语法结构的树形表示方式,语法树的每一个节点都代表着程序中的一个语法结构(Construct),例如包、类型、修饰符、运算符、接口、返回值甚至代码注释等都可以是一个语法结构。

(2)符号填充表(目前这点知识我不是很理解)

  完成词法分析和语法分析后,下一步就是填充符号表的过程,符号表(Symbol Table)是由一组符号地址和符号信息构成的表格,可以将它想象成哈希表中K-V键值对的形式(实际上符号表不一定是哈希表实现,可以是有序符号表、树状符号表、栈结构符号表等)。符号表中所登记的信息在编译的不同阶段都要用到。在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否一致)和产生中间代码。在目标代码生成阶段,当对符号表名进行地址分配时,符号表是地址分配的依据。

(3)注解处理器

  在JDK 1.5之后,Java语言提供了对注解(Annotation)的支持,这些注解与普通的Java代码一样,是在运行期间发挥作用的。在JDK 1.6中提供了一组插入式注解处理器的标准API在编译期间对注解进行处理,我们可以把它看做是一组编译器的插件,在这些插件里面可以读取、修改、添加抽象语法树中的任意元素。如果这些插件在处理注解期间对语法树进行修改,编译器将回到解析及填充符号表的过程重新处理,直到所有插入式注解处理器都没有再对语法树进行修改为止,每一次循环称为一个Round,也就是上图的回环过程。

  有了编译器注解处理器的标准API后,我们的代码才有可能干涉编译器的行为,由于语法树中的任意元素,甚至包括代码注释都可以在插件中访问到,所以通过插入式注解处理器实现的插件功在功能上有很大的发挥空间。

(4)语义分析与字节码生成

  语义分析之后,编译器获得了程序代码的抽象语法树表示,语法树能表示一个结构正确的源程序的抽象,但无法表示源程序是否符合逻辑。而语义分析的主要任务是对结构上正确的源程序进行上下文有关性质的审查,如进行类型审查!

  javac分析过程分为标注检查以及数据及控制流分析;

  a) 标注检查

int a = 1;
boolean b = false;
char c = 2;

  后续可能会出现的赋值运算:

int d = a + c;
int d = b + c;
char d = a + c;

   后续代码中如果出现了如上3中赋值运算的话,那它们都能构成结构正确的语法树,但是只有第1种的写法在语义上是没有问题的,能够通过编译,其余两种在Java语言中是不合逻辑的,无法编译(是否符合语义逻辑必须在具体的语言与具体的上下文环境之中才有意义)。

  b) 数据及控制流分析

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

  c) 语法糖

  语法糖是指在计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员的使用。Java中最常用的语法糖主要是泛型、变长参数、自动装箱/拆箱、条件编译等,虚拟机不支持这些语法,他们在编译阶段还原回简单的基础语法结构(泛型的擦除、变长参数封装成数组参数、Integer自动装箱拆箱变为Integer.value()等、分支不成立的代码块清除掉)。

(4)字节码生成

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

二、Java语法糖的味道

早期javac编译器优化的更多相关文章

  1. 早期(编译器)优化--javac编译器

    java语言的“编译期”其实是一段“不确定”的操作过程,可能是指一个前端编译器把.java变成.class的过程,也可能是指虚拟机的后端运行期编译器(JLT)把字节码转变成机器码的过程,也有可能是使用 ...

  2. Javac编译器详解

    学习<深入了解Java虚拟机>有一段时间了,大概理解了Java从源代码编译到执行出结果的过程,也能明确的知道Java是半解释性语言.在执行源代码时,先通过Javac编译器对源代码进行词法分 ...

  3. 《深入理解Java虚拟机》-----第10章 程序编译与代码优化-早期(编译期)优化

    概述 Java语言的“编译期”其实是一段“不确定”的操作过程,因为它可能是指一个前端编译器(其实叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;也可能是指虚拟机的后端运 ...

  4. java编译器优化和运行期优化

    概述    最近在看jvm优化,总结一下学习的相关知识 (一)javac编译器 编译过程 1.解析与填充符号表过程 1).词法.语法分析    词法分析将源代码的字符流转变为标记集合,单个字符是程序编 ...

  5. 探索c#之尾递归编译器优化

    阅读目录: 递归运用 尾递归优化 编译器优化 递归运用 一个函数直接或间接的调用自身,这个函数即可叫做递归函数. 递归主要功能是把问题转换成较小规模的子问题,以子问题的解去逐渐逼近最终结果. 递归最重 ...

  6. VS编译器优化诱发一个的Bug

    VS编译器优化诱发一个的Bug Bug的背景 我正在把某个C++下的驱动程序移植到C下,前几天发生了一个比较诡异的问题. 驱动程序有一个bug,但是这个bug只能 Win32 Release 版本下的 ...

  7. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part6:Move语义和编译器优化

    本文为第六部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  8. Visual C++中的编译器优化

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:Visual C++中的编译器优化.

  9. gcc编译器优化给我们带来的麻烦???

    gcc编译器优化给我们带来的麻烦??? 今天看到一个很有趣的程序,如下: ? 1 2 3 4 5 6 7 8 9 int main() {     const int a = 1;     int * ...

随机推荐

  1. poj1639,uva1537,uvalive2099,scu1622,fzu1761 Picnic Planning (最小限制生成树)

    Picnic Planning Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10742   Accepted: 3885 ...

  2. java中true是关键字吗

    java中的关键字有哪些? 答:1)48个关键字:abstract.assert.boolean.break.byte.case.catch.char.class.continue.default.d ...

  3. 常用手册或官网的url

    1.mysql--> https://www.mysql.com/ 2.菜鸟教程--> http://www.runoob.com 3.maven官网--> https://mave ...

  4. jsp 记录1 bs/cs

    1.jsp = html + js + css + jsp语法 + Java片段: 2.jsp是基于Java语言的,具有跨平台性: 3.jsp编译后的class文件会常驻内存中,运行速度快,对服务器的 ...

  5. 微服务从nacos配置中心获得配置信息

    一,安装nacos, 略 二,创建父工程和微服务工程 service1, service2,以idea为例 1, new -> project -> Maven -> 填写group ...

  6. pyqt设置窗口图标

    import sys from PyQt5.QtWidgets import QMainWindow,QApplication from PyQt5.QtGui import QIcon ''' 窗口 ...

  7. C1. Pokémon Army (easy version) 解析(DP)

    Codeforce 1420 C1. Pokémon Army (easy version) 解析(DP) 今天我們來看看CF1420C1 題目連結 題目 對於一個數列\(a\),選若干個數字,求al ...

  8. D. Design Tutorial: Inverse the Problem 解析含快速解法(MST、LCA、思維)

    Codeforce 472D Design Tutorial: Inverse the Problem 解析含快速解法(MST.LCA.思維) 今天我們來看看CF472D 題目連結 題目 給你一個\( ...

  9. Spring 最常用的 7 大类注解,哪些你还不知道?

    随着技术的更新迭代,Java5.0开始支持注解.而作为java中的领军框架spring,自从更新了2.5版本之后也开始慢慢舍弃xml配置,更多使用注解来控制spring框架. 而spring的的注解那 ...

  10. 隐马尔科夫模型 HMM(Hidden Markov Model)

    本科阶段学了三四遍的HMM,机器学习课,自然语言处理课,中文信息处理课:如今学研究生的自然语言处理,又碰见了这个老熟人: 虽多次碰到,但总觉得一知半解,对其了解不够全面,借着这次的机会,我想要直接搞定 ...