javac编译的四个主要的流程:
  • 词法分析器:将源码转换为Token流
    • 将源代码划分成一个个Token(找出java语言中的关键字)
  • 语法分析器:将Token流转化为语法树
    • 将上述的一个个Token组成一句句话(或者说成一句句代码块),检查这一句句话是不是符合Java语言规范(如if后面跟的是不是布尔判断表达式)
  • 语义分析器:将语法树转化为注解语法树
    • 将复杂的语法转化成简单的语法(eg.注解、foreach转化为for循环、去掉永不会用到的代码块)并做一些检查,添加一些代码(默认构造器)
  • 代码生成器:将注解语法树转化为字节码(即将一个数据结构转化成另一个数据结构)

第一:词法分析器

  

目的:将源码转换为Token流

流程:

一个字符一个字符的读取源代码,形成规范化的Token流。规范化的Token包含:

  • java关键词:package、import、public、class、int等
  • 自定义单词:包名、类名、变量名、方法名
  • 符号:=、;、+、-、*、/、%、{、}等

源码关键:

词法分析过程是在的JavacParser.parseCompilationUnit()中完成的

com.sun.tools.javac.parser.JavacParser  规定哪些词符合Java语言规范,具体读取和归类不同词法的操作由scanner完成
com.sun.tools.javac.parser.Scanner  负责逐个读取源代码的单个字符,然后解析符合Java语言规范的Token序列,调用一次nextToken()都构造一个Token
com.sun.tools.javac.parser.Tokens$TokenKind  里面包含了所有token的类型,譬如BOOLEAN,BREAK,BYTE,CASE。
com.sun.tools.javac.util.Names  用来存储和表示解析后的词法,每个字符集合都会是一个Name对象,所有的对象都存储在Name.Table这个内部类中。
com.sun.tools.javac.parser.KeyWords  负责将字符集合对应到token集合中,如,package zxy.demo.com; Token.PACKAGE = package, Token.IDENTIFIER = zxy.demo.com,(这部分又分为读取第一个token,为zxy,判断下一个token是否为“.”,是的话接着读取下一个Token.IDENTIFIER类型的token,反复直至下一个token不是”.”,也就是说下一个不是Token.IDENIFIER类型的token,Token.SEMI = ;即这个TIDENTIFIER类型的token的Name读完),KeyWords类负责此任务。

第二:语法分析器

目的:将进行词法分析后形成的Token流中的一个个Token组成一句句话,检查这一句句话是不是符合Java语言规范。

流程:

  • package
  • import
  • 类(包含class、interface、enum),一下提到的类泛指这三类,并不单单是指class

源码关键:

com.sun.tools.javac.tree.TreeMaker  所有语法节点都是由它生成的,根据Name对象构建一个语法节点
com.sun.tools.javac.tree.JCTree$JCIf   所有的节点都会继承jctree和实现**tree,譬如 JCIf extends JCTree.JCStatement implements IfTree
com.sun.tools.javac.tree.JCTree的三个属性

    • Tree tag:每个语法节点都会以整数的形式表示,下一个节点在上一个节点上加1;
    • pos:也是一个整数,它存储的是这个语法节点在源代码中的起始位置,一个文件的位置是0,而-1表示不存在
    • type:它代表的是这个节点是什么java类型,如int,float,还是string等

第三:语义分析器

目的:将语法树转化为注解语法树

流程:

  • 添加默认的无参构造器(在没有指定任何有参构造器的情况下),把引用其他类的方法或者变量,抑或是继承实现来的变量和方法等输入到类自身的符号表中
  • 处理注解
  • 标注:检查语义合法性、进行逻辑判断
    • 检查语法树中的变量类型是否匹配(eg.String s = 1 + 2;//这样"="两端的类型就不匹配)
    • 检查变量、方法或者类的访问是否合法(eg.一个类无法访问另一个类的private方法)
    • 变量在使用前是否已经声明、是否初始化
    • 常量折叠(eg.代码中:String s = "hello" + "world",语义分析后String s = "helloworld")
    • 推导泛型方法的参数类型
  • 数据流分析
    • 变量的确定性赋值(eg.有返回值的方法必须确定有返回值)
    • final变量只能赋一次值,在编译的时候再赋值的话会报错
    • 所有的检查型异常是否抛出或捕获
    • 所有的语句都要被执行到(return后边的语句就不会被执行到,除了finally块儿)
  • 进一步语义分析
    • 去掉永假代码(eg.if(false))
    • 变量自动转换(eg.int和Integer)自动装箱拆箱
    • 去掉语法糖(eg.foreach转化为for循环,assert转化为if,内部类解析成一个与外部类相关联的外部类)
  • 最后,将经过上述处理的语法树转化为最后的注解语法树

源码关键:

com.sun.tools.javac.comp.Enter  将java类中的符号输入到符号表中,主要是两个步骤:

  • 将所有类中出现的符号输入到类自身的符号表中,所有类符号、类的参数类型符号(泛型参数类型)、超类符号和继承的接口类型符号等都存储到一个未处理的列表中。
  • 将这个未处理的列表中所有的类都解析到各自的类符号列表中,这个操作是在MemberEnter.complete()中完成(默认构造器也是在这里完成的)。

com.sun.tools.javac.processing.JavacProcessingEnvironment  处理注解

com.sun.tools.javac.comp.Attr  检查语义的合理性并进行逻辑判断,类型是否匹配,是否初始化,泛型是否可推导,字符串常量合并

com.sun.tools.javac.comp.Check  协助attr,变量类型是否正确

com.sun.tools.javac.comp.Resolve  协助attr,变量方法类的访问是否合法,是否是静态变量

com.sun.tools.javac.comp.ConstFold  协助attr,常量折叠

com.sun.tools.javac.comp.Infer  协助attr,推导泛型

com.sun.tools.javac.comp.Flow  数据流分析和替换等价源代码的分析(即上面的进一步语义分析)

第四:代码生成器

目的:将注解语法树转化成字节码,并将字节码写入*.class文件。

流程:

  • 将java的代码块转化为符合JVM语法的命令形式,这就是字节码
  • 按照JVM的文件组织格式将字节码输出到*.class文件中

源码关键:

com.sun.tools.javac.jvm.Gen  遍历语法树生成最终的java字节码
com.sun.tools.javac.jvm.Items  辅助gen,这个类表示任何可寻址的操作项,这些操作项都可以作为一个单位出现在操作栈上
com.sun.tools.javac.jvm.Code  辅助gen,存储生成的字节码,并提供一些能够影射操作码的方法

Javac编译原理 《深入分析java web 技术内幕》第四章的更多相关文章

  1. Servlet工作原理解析 《深入分析java web 技术内幕》第九章

    参考关于servblet的相关文章 侧重概况:https://blog.csdn.net/levycc/article/details/50728921 ibm的相关:https://www.ibm. ...

  2. 深入分析Java Web技术内幕(修订版)

    阿里巴巴集团技术丛书 深入分析Java Web技术内幕(修订版)(阿里巴巴集团技术丛书.技术大牛范禹.玉伯.毕玄联合力荐!大型互联网公司开发应用实践!) 许令波 著   ISBN 978-7-121- ...

  3. JAVA Coder 的《深入分析Java Web 技术内幕》读书笔记

    本文基于<深入分析Java Web 技术内幕> <深入分析Java Web 技术内幕>,作者是 许令波,电子工业出版社.本文只是记录书本当中的精彩部分,作个人回顾和技术分享,请 ...

  4. developerWorks 图书频道: 深入分析 Java Web 技术内幕,第 10 章

    developerWorks 图书频道: 深入分析 Java Web 技术内幕,第 10 章 深入理解 Session 与 Cookie Session 与 Cookie 不管是对 Java Web ...

  5. 《深入分析Java Web技术内幕》读书笔记 - 第1章 深入Web请求过程

    第1章 深入Web请求过程 1 1.1 B/S网络架构概述 2 基于统一的应用层协议HTTP来交互数据. 1.2 如何发起一个请求 4 HTTP连接本质是建立Socket连接.请求实现方式:工具包如H ...

  6. 深入分析java web技术内幕目录一览

    Web请求过程 如何发起请求:browser,httpclient http解析:chrome ,cache Dns域名解析:域名缓存 cdn:负载,动态加速,回源 Java I/O I/0类库的基本 ...

  7. 深入分析Java Web技术内幕

    深入web请求过程 发起一个http请求的过程就是建立一个socket通信的过程 HTTPClient是一个开源的实现了http请求的工具包 深入分析java I/O的工作机制 深入分析java We ...

  8. JVM内存管理 《深入分析java web 技术内幕》第八章

    8.1 物理内存与虚拟内存 物理内存RAM(随机存储器),寄存单元为寄存器,用于存储计算单元执行指令的中间结果. 连接处理器和RAM或者处理器和寄存器的是地址总线,这个地址的宽度影响了物理地址的索引范 ...

  9. 读书笔记之深入分析Java Web技术内幕

    章节: 1 B/SB/S的优点: 客户端使用统一的浏览器(Browser) ,浏览器的统一带来了操作的统一,无论使用什么服务,因为浏览器是相同的,所以操作类似.客户使用简单了.服务端开发简化; 使用统 ...

随机推荐

  1. JavaScript是如何工作的:深入类和继承内部原理 + Babel和TypeScript之间转换

    现在构建任何类型的软件项目最流行的方法这是使用类.在这篇文章中,探讨用 JavaScript 实现类的不同方法,以及如何构建类的结构.首先从深入研究原型工作原理,并分析在流行库中模拟基于类的继承的方法 ...

  2. java super和this总结

    今天群里有人问我怎么复写父类的构造函数,我当时听错了以为是一般方法,然后就对他说只要同名就可以,然后他告诉我错了,我再仔细看,才知道他问的是复写 父类的构造方法,其实自己也不知道子类能不能复写父类的构 ...

  3. Kubernetes 中的核心组件与基本对象概述

    Kubernetes 是 Google 基于 Borg 开源的容器编排调度,用于管理容器集群自动化部署.扩容以及运维的开源平台.作为云原生计算基金会 CNCF(Cloud Native Computi ...

  4. mysql 开发基础系列22 SQL Model

    一.概述 与其它数据库不同,mysql 可以运行不同的sql model 下, sql model 定义了mysql应用支持的sql语法,数据校验等,这样更容易在不同的环境中使用mysql. sql ...

  5. 另类SQL拼接方法

    在编写SQL的时候经常需要对SQL进行拼接,拼接的方式就是直接String+处理,但这种情况有个不好的地方就是不能对SQL进行参数化处理.下面介绍一种就算基于String +的方式也可以进行SQL参数 ...

  6. .NET西安社区 [拥抱开源,又见 .NET] 活动简报

    拥抱开源, 又见 .NET」 随着 .NET Core的发布和开源,.NET又重新回到了人们的视野.除了开源.跨平台.高性能以及优秀的语言特性,越来越多的第三方开源库也出现在了Github上——包括M ...

  7. 使用Eclipse创建SpringBoot项目

    1  首先我们需要安装STS插件:Help--> Eclipse Marketplace 安装成功之后,会让你重启eclipse. 2  然后 File-->New--->Proje ...

  8. Android View 的事件分发原理解析

    作为一名 Android 开发者,每天接触最多的就是 View 了.Android View 虽然不是四大组件,但其并不比四大组件的地位低.而 View 的核心知识点事件分发机制则是不少刚入门同学的拦 ...

  9. awk知识点总结

    find+xargs+grep+sed+awk系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 0.学习资料推荐 1.awk入门:看视频.找 ...

  10. 业务开发(八)—— Maven

    0x01.maven install成功后,项目旁边依然有个红叉 maven--update--选中下方Force Update of Snapsshots/Releases 0x02.An inte ...