最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

天天快看:13 Javac将源码编译为字节码的过程

来源:博客园
目录
  • 1 编译器分类
  • 2 Javac编译器
    • 2.1 Javac简介
    • 2.2 Javac与程序开发
  • 3 Javac工作过程
    • 3.1 解析与填充符号表
      • 3.1.1 词法分析
      • 3.1.2 语法分析
      • 3.1.3 填充符号表
    • 3.2 注解处理
    • 3.3 语义分析
      • 3.3.1 标注检查
      • 3.3.2 数据及控制流分析
      • 3.3.3 解语法糖
    • 3.4 生成字节码
  • 4 总结

1 编译器分类

Java的编译过程:将源代码转化成机器可执行的二进制代码。实际上,编译过程,是分阶段进行的,由此产生了不同的编译器。

编译器分类:

类别工作内容代表
前端编译器源代码转变成字节码JDK的Javac、Eclipse编译器(ECJ)
即时编译器运行时把字节码转变成本地机器码HotSpot虚拟机的C1、C2编译器
提前编译器直接把源代码编译成与目标机器指令集相关的二进制代码JDK的Jaotc等

2 Javac编译器

2.1 Javac简介

  1. Javac是程序猿使用最多的一款编译器,但面向IDE编程使得我们很少直接使用javac,开发工具帮我们自动编译了
  2. 它由Java编写

IntelliJ IDEA ,支持几种编译器:Javac、Eclipse ECJ、Ajc 等,默认使用Javac


(资料图片仅供参考)

2.2 Javac与程序开发

编译器如何跟程序员打交道?

  1. 前端编译器对程序效率提升影响极少。虚拟机设计团队将性能优化放在即时编译器中,让那些不是由Javac产生的Class文件(如JRuby、Groovy等语言的Class文件)也能被编译器优化。
  2. 前端编译器对程序员开发效率提升影响极大:编译器的“语法糖”:泛型、自动拆箱、自动装箱、枚举类、Lambda表达式等特征,简化编码。

3 Javac工作过程

Javac工作过程就是源代码变为字节码的过程。

3.1 解析与填充符号表

3.1.1 词法分析

  1. 将源代码的字符流转变为标记集合(Token)。
  2. 单个字符是编码的最小元素,标记是编译时的最小元素。关键字、变量名、字面量、运算符都可以作为标记
  3. 因此:词法分析就是将源代码拆解关键字。源代码->关键词集合
int a = 100 这句代码包含4个标记,分别是int、a、=、100,虽然关键字int由3个字符构成,但是它是一个独立的标记,不可拆分

3.1.2 语法分析

  1. 根据标记序列构造抽象语法树(AST)
  2. 每一个节点代表代码中的一个语法结构,例如包、类型、修饰符、运算符、接口、返回值
  3. 源代码->关键词集合->语法树

注意:生成语法树以后,编译器后续的操作都是基于语法树,不再操作源码

AST View 插件生成抽象语法树:

上图看着复杂,换个图ps:我没分析javac源代码,借用网图:java编译器源码解析-语法分析(1)

3.1.3 填充符号表

先理解符号概念,参考:java编译器源码解析-语义分析-填充符号表

一、 符号是什么?

  1. java声明一个类,类中有属性和方法,计算机识别为符号;
  2. 符号有名称,如:类名、方法名、属性名;
  3. 符号有类型,如:int a=0;a是一个变量,但编译器认为a是一个VarSymbol,它的类型是JCPrimitiveType

二、符号表什么时候生成?生成语法树之后

三、符号地址代表什么?内存地址,在目标代码生成阶段,会对符号名进行地址分配

四、符号内容有什么?地址、内容

五、填充前后有什么变化?在语法树的基础上进一步完善信息

填充符号表

  1. 生成一组符号地址符号信息构成的数据结构(类比哈希表中键值对)

3.2 注解处理

插入式注解处理器,编译期间处理注解,读取,修改,删除语法树中的任意元素,编译器会根据修改与否,重新回到解析及符号表填充阶段进行处理。

Lombok:基于插入式注解处理器实现的插件,修改语法树元素CheckStyle、FindBug、Klocwork:遍历和分析语法树,分析代码质量

3.3 语义分析

对语法树进行逻辑验证

3.3.1 标注检查

变量是否先声明后使用、变量类型与值对否匹配

常量折叠:“a=1+2”优化为“a=3”

3.3.2 数据及控制流分析

检验:局部变量先赋值后使用、方法的每条路径是否都有返回值

跟类加载时的校验过程类似

3.3.3 解语法糖

java虚拟机不支持泛型、装箱、拆箱、变长参数等语法解语法糖:编译阶段还原到基础语法结构

3.4 生成字节码

将语法树、符号表转化成字节码指令,生成.class文件将实例构造器()方法和类构造器()方法添加到语法树中

4 总结

Javac编译过程各节点及说明:

Javac编译过程中的主体代码及其功能:

关键词: 词法分析 语法分析 语义分析