早期javac编译器优化
学习《深入了解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编译器优化的更多相关文章
- 早期(编译器)优化--javac编译器
java语言的“编译期”其实是一段“不确定”的操作过程,可能是指一个前端编译器把.java变成.class的过程,也可能是指虚拟机的后端运行期编译器(JLT)把字节码转变成机器码的过程,也有可能是使用 ...
- Javac编译器详解
学习<深入了解Java虚拟机>有一段时间了,大概理解了Java从源代码编译到执行出结果的过程,也能明确的知道Java是半解释性语言.在执行源代码时,先通过Javac编译器对源代码进行词法分 ...
- 《深入理解Java虚拟机》-----第10章 程序编译与代码优化-早期(编译期)优化
概述 Java语言的“编译期”其实是一段“不确定”的操作过程,因为它可能是指一个前端编译器(其实叫“编译器的前端”更准确一些)把*.java文件转变成*.class文件的过程;也可能是指虚拟机的后端运 ...
- java编译器优化和运行期优化
概述 最近在看jvm优化,总结一下学习的相关知识 (一)javac编译器 编译过程 1.解析与填充符号表过程 1).词法.语法分析 词法分析将源代码的字符流转变为标记集合,单个字符是程序编 ...
- 探索c#之尾递归编译器优化
阅读目录: 递归运用 尾递归优化 编译器优化 递归运用 一个函数直接或间接的调用自身,这个函数即可叫做递归函数. 递归主要功能是把问题转换成较小规模的子问题,以子问题的解去逐渐逼近最终结果. 递归最重 ...
- VS编译器优化诱发一个的Bug
VS编译器优化诱发一个的Bug Bug的背景 我正在把某个C++下的驱动程序移植到C下,前几天发生了一个比较诡异的问题. 驱动程序有一个bug,但是这个bug只能 Win32 Release 版本下的 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part6:Move语义和编译器优化
本文为第六部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- Visual C++中的编译器优化
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:Visual C++中的编译器优化.
- gcc编译器优化给我们带来的麻烦???
gcc编译器优化给我们带来的麻烦??? 今天看到一个很有趣的程序,如下: ? 1 2 3 4 5 6 7 8 9 int main() { const int a = 1; int * ...
随机推荐
- Spring官方都推荐使用的@Transactional事务,为啥我不建议使用!
GitHub 17k Star 的Java工程师成神之路,不来了解一下吗! GitHub 17k Star 的Java工程师成神之路,真的不来了解一下吗! GitHub 17k Star 的Java工 ...
- 第二十六章 ansible主要模块介绍
一.Ansible模块回顾 1.command模块 [root@m01 ~]# ansible web01 -m command -a 'free -m' 2.shell模块 #支持管道符这种特殊符号 ...
- java 保留小数点后指定位数四种方法
1 package com.itheima_01; 2 3 import java.math.BigDecimal; 4 import java.text.DecimalFormat; 5 impor ...
- Git版本管理器操作步骤
组长建立管理器: 第一步: 管理器网址:https://gitee.com/ 第二步:注册个人信息 第三步(添加项目) 第四步(兴建文件)注意:必须双层文件夹 第五步:打开VS开发工具 第六步:去把刚 ...
- 【Azure微服务 Service Fabric 】因证书过期导致Service Fabric集群挂掉(升级无法完成,节点不可用)
问题描述 创建Service Fabric时,证书在整个集群中是非常重要的部分,有着用户身份验证,节点之间通信,SF升级时的身份及授权认证等功能.如果证书过期则会导致节点受到影响集群无法正常工作. 当 ...
- 使用Navicat远程连接阿里云ECS服务器上的MySQL数据库
一.必须给服务器的安全组规则设置端口放行规则,在管理控制台中设置: 之后填写配置,授权对象是授权的IP,其中0.0.0.0/0为所有IP授权,之后保存; 二.Navicat使用的配置 在编辑连接处,要 ...
- 用python写一个豆瓣短评通用爬虫(登录、爬取、可视化)
原创技术公众号:bigsai,本文在1024发布,祝大家节日快乐,心想事成. @ 目录 前言 登录 爬取 储存 可视化分析 前言 在本人上的一门课中,老师对每个小组有个任务要求,介绍和完成一个小模块. ...
- git每次提交代码都要设置账号密码的问题
git config --global credential.helper store 待下一次提交代码的时候,输入了正确的用户名和密码,之后 就不需要输入用户名密码
- python使用redis缓存数据库
Redis 关注公众号"轻松学编程"了解更多. Windows下直接解压可用,链接:https://pan.baidu.com/s/1rD4ujoN7h96TtHSu3sN_hA ...
- MIT黑科技:通过手机记录的咳嗽数据检测是否感染新冠病毒
这次的新冠状病毒虽然没有2002年的SARS破坏力那么强悍,但其可怕之处是长时间的无症状潜伏,使得被感染者在不知情的情况下,将病毒散播出去.如果没有强有力的防疫手段,病毒的传播几乎难以控制.而防止病毒 ...