Java中的编译分为两个部分:

源码文件编译成字节码文件(前端编译)

字节码文件被虚拟机加载以后编译成机器码(后端编译)

对于开发来说接触的一般都是第一个步骤也就是源码编译成字节码文件(class文件),第二个步骤开发几乎不会接触,因为这是虚拟机在运行过程中自己做的一些编译流程,将字节码转换成可被虚拟机识别执行的机器码。

1. 前端编译

前端编译大致主要有以下流程:

对源文件进行词法分析产生字符流

对字符流进行语法分析产生抽象语法树

对语法树进行语义分析,确保语义正常

语义分析通过以后生成中间代码(字节码)

下面我们站在javac的角度上看,编译过程大致分为:

解析与填充符号表

插入式注解处理器的处理注解

语义分析与字节码的生成

上述3个过程会包含前段编译4个步骤的所有流程,下面我们看一下这个3个步骤需要做什么。

2. 解析与填充符号表

2.1 解析

2.1.1 词法分析

Java源文件是由一个个字符构成,但是编译器所能识别的是Token(标记)。我们需要通过词法分析来将源文件中的字符流转换成Token集合,这样才能用于后续的语法分析。

int a = b + c;

int是由3个字符构成,但是对于词法分析来说,这三个字符会被解析成一个Token(标记)。

词法分析主要由com.sun.tools.javac.parser.Scannaer类来实现。

2.1.2 语法分析

根据Token集合生成抽象语法树,语法树是一种用来表示程序代码语法结构的表现形式,语法树的每一个节点都代表着程序代码中的一个语法结构,例如包、类型、修饰符。

package jvm;

/**

* @author sh

*/

public class ClassTest{

public int add(int a, int b){

return a + b;

}

}

语法分析主要有com.sun.tools.javac.parser.Parser类来实现。

上述这段代码生成的抽象语法树如下(IDEA  JDT AstView插件可以查看抽象语法树):

上述抽象语法树在Java中使用com.sun.tools.javac.tree.JCTree类来表示,之后所有的操作均建立在抽象语法树之上。

2.2 填充符号表

结束了词法分析和语法分析以后,下一步就是填充符号表。符号表中信息可以用在语义分析过程中的检查和产生中间代码

3. 注解处理器

注解处理器在编译期间对注解进行处理,可以读取、修改、添加抽象语法树中的任意元素。如果注解处理器对语法树进行了修改,编译器将会回到解析和填充符号表的过程重新处理,直到注解处理器不再对语法树进行修改为止,每一次循环称为一个Round。

4. 语义分析和字节码生成

4.1 语义分析

语义分析主要是对程序上下文进行检查,如变量类型检查。

语义分析主要包含两个步骤:

标注检查

数据及控制流分析

4.1.1 标注检查

标注检查主要用来检查变量是否已被声明、变量与赋值之间的数据类型是否匹配。在标注检查的步骤中还会实施常量折叠。

int a = 1 + 2;

上述代码我们在语法树上可以看到字面量1、2以及操作符+,在经过常量折叠步骤以后,会生成一个新的字面量3,在程序运行时a的值就是3,不会再消耗CPU进行计算。

4.1.2 数据及控制流分析

数据及控制流分析是对程序上下文逻辑进行验证,检查局部变量是否在使用前已经赋值、方法的每条路径都有返回值、所有的受检查异常是否被正确处理。

局部变量final类型的变量的不变性只能依靠编译来保证,这是因为局部变量在常量池中没有CONSTANT_Fieldref_info的符号引用,没有访问标志的信息,在运行期虚拟机并不确定局部变量是否是final,因此需要编译期的保证。

4.2 字节码生成

字节码在生成之前,还需要进行最后一项工作解语法糖。

4.2.1 解语法糖

Java中的语法糖包括范型、变长参数、自动装箱/拆箱、Lambda。

语法糖可以增加程序的可读性、减少代码量。

4.2.2 字节码生成

字节码生成是javac编译的最后一个阶段。字节码生成阶段不仅仅是把各个步骤生成的信息转换成字节码写到磁盘,还进行了代码的添加和转换工作。

将static语句块、static变量收敛到

方法中

将实例变量初始化、调用父类构造器收敛到

方法

程序优化,比如将字符串的+操作替换成StringBuilder的append

完成了语法树的遍历和调整以后,就会填充了所有信息的符号表交给com.sun.tools.javac.jvm.ClassWriter类,最后由该类的writeClass()方法输出字节码。

本期的Java前端编译介绍到这,我们下期再见!!!

我是shysh95,希望可以和你专注技术的路上并肩作战,长按识别或者扫码关注微信公众号,更多精彩文章!!!

java 编译原理 字符串_Java编译原理(javac)相关推荐

  1. java枚举返回字符串_Java新特性:数据类型可以扔掉了?

     关注"脚本之家",与百万开发者在一起 作者 | 王磊 来源 | Java中文社群(ID:javacn666) 在很久很久以前,我们写代码时要慎重的考虑变量的数据类型,比如下面这些 ...

  2. java substring截取字符串_java基础教程之字符串的介绍,比较重要的一个知识点【下】...

    字符串操作 1.获取子字符串 通过String类的substring()方法可对字符串进行截取.这些方法的共同点就是都是利用字符串的下标进行截取.应明确字符串下标是从0开始的. substring() ...

  3. java十六进制与字符串_JAVA十六进制与字符串的转换方法

    JAVA十六进制与字符串的转换方法 在java程序中,十六进制与字符串是怎么转换的呢?下面yjbys小编就为大家分享JAVA十六进制与字符串的转换方法,一起来看看吧! 第一种方法: 将指定byte数组 ...

  4. java正则表达式匹配字符串_java正则表达式如何匹配字符串

    java正则表达式匹配字符串的方法:使用tostring,代码为[while(matcher.find()){tmp.add(matcher.group(1).toString());}]. java ...

  5. java怎么输出字符串_java输出字符串,怎么样输出字符串?

    下面要给大家讲的就是java输出字符串的问题,那么java怎样输出字符串呢?具体要怎样操作?一起来了解一下. 一般在java编程的过程当中,经常会使用System.out.println();来输出字 ...

  6. 电脑配置java编译报错_java 编译错误

    我有两个简单的代码,ClickMe.java代码为:importjava.applet.Applet;importjava.awt.*;importjava.awt.event.*;publiccla ...

  7. java编译生成哪些文件_java编译后生成什么文件?生成的文件包括什么?

    在大家编译完java程序的时候,都是会生成一个文件的,作为java新手不清楚java编译后生成什么文件?那么今天我们就给大家讲解一下这方面的内容,大家可以参考下文哦! java文件编译过后会生成一个c ...

  8. java引用类型有啥_Java引用类型原理深度剖析,看完文章,90%的人都收藏了

    Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference):强引用.软引用.弱引用.虚引用.其中强引用就是我们经常使用的Object a = new Object(); ...

  9. JAVA三角形边长定义_Java编译:定义三角形的三条边长a=4,b=8.54,c=4.44;求三角形的周长d...

    共回答了20个问题采纳率:95% (package/import/class声明 省略) public static void main(String [] arg) { float a = 4f; ...

最新文章

  1. win10进不了微软服务器,Microsoft帐户无法登录怎么办 Win10微软账户登录不上解决方法...
  2. 域创实业谋定功能性-农业大健康·万祥军:借创新引领潮流
  3. 后端技术:JDK 8 Stream 数据流效率测试
  4. 【转】使用JMeter对数据库做压力测试
  5. 服务器root账号用户名和密码忘记了,宝塔忘记后台管理员账号密码怎么办?教你用这条命令轻松搞定...
  6. transition css3 渐变效果
  7. linux htdocs目录下,ubuntu解决htdocs目录的权限问题
  8. Android学习视频集合
  9. 4399ATAPI讲解用例配置篇
  10. [含论文+答辩PPT+任务书+中期检查表+源码等]S2SH洋酒销售系统|商城
  11. 测试开发大厂面试精选40题
  12. Vue 脚手架 环境搭配
  13. Python函数学习心得
  14. 《孙子兵法》帮你找到合格的管理者
  15. Remarkable简单使用
  16. 电脑连接wifi总是断 手机正常 解决方案
  17. 学习记录:启动豌豆荚进入软件界面
  18. UnsatisfiedDependencyException: Error creating bean with name XXXController'
  19. 云计算之路-阿里云上:在乌云中坚信蓝天
  20. python独立网站教程_python做网站教程_如何免费做网站的教程

热门文章

  1. Swift傻傻分不清楚系列(十)枚举
  2. [scrum]2011/9/24-----第四天
  3. 20172311 2017-2018-2 《程序设计与数据结构》第八周学习总结
  4. 两张神图介绍python3和 2.x与 3.x 的区别
  5. VS2012生成事件
  6. 1 用存储过程实现分页,除了上一页,下一页,第一页,和末页外还要有go按钮,以及go到那里的文本框。另外还要在Lable显示“当前x页,一共y页”。注意验证控件的使用和 链接存储过程的内容。...
  7. Spring--Context
  8. js中字符串编码函数escape()、encodeURI()、encodeURIComponent()区别详解
  9. jquery --- 阻止表单默认的提交行为,标准化表单的数据
  10. 算法 --- 快慢指针判断链表是否有环