🕉️ 前端编译 & 优化
2022年6月20日
- Java
🕉️ 前端编译 & 优化
1. 前端编译
1) 编译:
- 前端编译器: JDK 的
Javac
- 几乎没有优化措施,对性能的优化主要集中在运行期的 JIT 中,这样可以使得非 Javac 产生的 Class 文件也可以享受到 JIT 优化的红利
- 即时编译器: HotSpot 的
C1
&C2
编译器 - 提前编译器
2) Javac 编译过程
2. 编译具体过程 & 相关优化
1) 词法分析 & 语法分析
- 词法分析
- 将
int a = b + 2
分解成int
a
=
b
+
2
- 将
- 语法分析
- 生成抽象语法树
2) 填充符号表
- 符号表类似于 K-V 的哈希结构
- 存放符号地址 & 符号信息
- 若未提供任何构造函数,则默认构造函数在此时添加
3) 注解处理器
JDK 5
提供了对注解的支持,用于运行期间发挥作用JKD 6
提供了插入式注解,可在编译期对特定注解进行处理,从而影响前端编译- 举例:
Lombok
通过注解自动生成getter
/setter
equals()
hashCode()
等方法
4) 语义分析
- 标注检查
- 变量使用前是否已被声明、变量与赋值之间的数据类型是否匹配
- 常量折叠
int a = 1 + 2
转换成int a = 3
- 数据 & 控制流分析
- 局部变量使用前是否被赋值
- 每条方法路径是否有返回值
- 所有受检异常是否被正确处理等
5) 解语法糖
- 泛型
- 类型擦除式泛型
- 只在程序源码中存在,在编译后的字节码文件中,被替换为原来的裸型,并在相应地方插入强制转换代码
- 变长参数
- 自动拆装箱
- 包装类的
==
只有在遇到算术运算符时才会自动拆装箱 - 包装类的
equals()
不处理数据类型的转换
- 包装类的
- 遍历循环
- 还原成 Iterator 的实现,因此要遍历的类必须实现 Iterator 接口
6)字节码生成
- 将语法树 & 符号表转换成字节码指令写入磁盘
- 进行少量代码添加 & 转换
- 添加实例构造器
<init>()
& 类构造器<clinit>()
- 添加实例构造器
3. 字节码
- 字节码属于
.Class
文件的一部分,具体为Class
文件的方法表中的Code
属性