深入理解java虚拟机读书笔记,第十章:早期(编译器)优化

10.1概述

Java语言的“编译期”其实是个“不确定”的过程:

前端编译器:把Java文件编译成class文件,例如Sun的javac、Eclipse JDT中的增量编译器(ECJ)

后端编译器(JIT编译器,just in time compiler):把字节码转换为机器码,例如HotSpotVM的C1、C2编译器

静态提前编译(AOT编译器,Ahead Of Time compiler):把Java直接编译为本地机器代码,例如:GNU Compiler for the Java(GCJ),Excelsior JET


本章提到的“编译器”和“编译期”指的是前端编译

javac做了许多针对Java语言编码过程的优化措施来改善程序员的编码风格和提高编码效率

即时编译器在运行期优化更重要,前端编译器对于程序编码来说关系更密切


10.2javac编译器

10.2.1Javac的源码和调试

编译的过程:

解析与填充符号表过程

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

分析与字节码生成过程


10.2.2解析与填充符号表

解析过程由parseFiles()方法完成,包含经典编译原理中的词法分析和语法分析

a>词法分析、语法分析

词法分析是将源代码的字符流转变为标记(Token)集合

词法分析由com.sun.tools.javac.parser.Scanner类实现


语法分析是根据Token序列构造抽象语法树的过程

语法分析由com.sun.tools.javac.parser.Parser类实现


抽象语法树(Abstract Syntax Tree,AST)是一种描述程序代码语法结构的树形式表现,每个节点代表程序中的语法结构(Construct),例如包、

类型、修饰符、运算符、接口、返回值甚至代码注释都可以作为语法结构

语法抽象树由java.sun.tools.javac.tree.JCTree表示


后续的操作都建立在语法树上

b>填充符号表

由enterTrees()方法完成

符号表(Symbol Table)是由一组符号地址和符号信息构成的表格

符号表中所登记的信息在编译的不同阶段都会用到,在语义分析中,用于语义检查和产生中间代码;在目标代码生成阶段,符号表是地址分配的

依据


过程由java.sun.tools.javac.comp.Enter类实现,出口是一个待处理列表


10.2.3注解处理器

注解与普通Java代码一样,在运行期发挥作用

jdk1.6提供了插入式注解处理器标准API在编译期间对注解进行处理,可以读取、添加、修改抽象语法树的任意元素

处理注解期间对语法树进行修改,编译器将进入解析与填充符号表阶段重新处理

初始过程由initProcessAnnotations()方法完成


10.2.4语义分析与字节码生成

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

a>标注检查

变量使用前是否被声明

变量与赋值之间的数据类型是否匹配

...

b>数据及控制流分析

对上下文逻辑的进一步校验


可以检查出

局部变量在使用前是否赋值

方法的每条路径是否有返回值

是否所有的受检异常都正确处理

...


c>解语法糖

语法糖:计算机语言中添加的某种语法,这种语法对于语言的功能并没有影响,但是更方便程序员使用

语法糖能够增加程序的可读性,从而减少程序代码的出错机会

Java语言中语法糖主要有:泛型,变长参数,自动装箱/拆箱


解语法糖:虚拟机运行时不支持语法糖,它们在编译阶段还原回简单的基础语法结构


d>字节码生成

将前面各个步骤生成的信息(语法树、符号表)转换为字节码写到磁盘中,还进行了少量的代码添加和转换工作

代码添加:实例构造器和类构造器在这个阶段添加到语法树

代码转换:字符串加操作替换为StringBuffer或者StringBuilder


10.3Java语法糖的味道

语法糖不会提供实质性的功能改进,但是或许能够提高效率、提升语法严谨性、减少编码出错的机会

10.3.1泛型与类型擦除

泛型的本质是参数化类型(Parametersized Type)的应用,也就是说所操作的数据类型被指定为一个参数

Java语言中的泛型只在源码中存在,在编译后的字节码中,就已经替换为原来的原生类型(Raw Type,也称为裸类型),所以泛型是java语言的一颗语法糖,Java语言中的泛型实现方法称为类型擦除,基于这种方法实现的泛型称为伪泛型


引入Signature、LocalVariableTable等属性用于解决伴随泛型而来的参数化类型的识别

Signature:作用是存储一个方法在字节码层面的特征签名,保存的类型不是原生类型,而是包含了参数化类型的信息

擦除法所谓的擦除,仅仅是对方法的code属性中的字节码进行擦除,实际上元数据中还是保留了泛型信息,这也是我们能够通过反射手段获取到参数化类型的根本依据


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

自动装箱、拆箱在编译后转换成了对应的包装和还原方法

遍历循环把代码还原成了迭代器的实现,所以被遍历的类需要实现Iterable接口


包装类的“==”运算在不遇到算出运算的情况下不会自动拆箱

包装类equals()方法不处理数据转型的关系


10.3.3条件编译

Java进行条件编译的方式是使用条件为常量的if语句


10.4实战:插入式注解处理器

10.4.1实战目标

使用注解处理器API来编写一款拥有自己风格的校验工具,来检查命名规范

10.4.2代码实现

注解API知识点:

实现注解处理的代码需要继承抽象类javax.annotation.processing.AbstractProcessor

类中只有一个需要覆盖的抽象方法process(Set annotations,RoundEnvironment roundEnv),从第一个参数annotations获取注解处理器需要处理的注解集合,从第二个参数roundEnv中访问到当前这个Round中的语法树节点

processingEnv代表注解处理器框架提供的一个上下文环境

@SupportedAnnonationTypes:代表这个注解处理器对哪些注解感兴趣,*作为通配符表示所有注解

@SupportedSourceVersion:代表这个注解处理器可以处理哪个版本的java代码

每个注解处理器都是单例的

如果不需要修改或者生成语法树的内容,则process()方法返回false

10.4.3运行与测试




参考文献:

[1] 深入理解Java虚拟机 第二版 --周志明


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容