「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战」
类加载过程
一个类的加载过程会经历加载、验证、准备、解析、初始化、使用、卸载七个阶段。
如下图所示:
加载
加载过程中,虚拟机需要完成的三件事:
- 通过类的全限定名来获取定义此类的二进制字节流
- 将此字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成代表这个类的java.lang.CLass对象,作为方法区这个类的各种数据访问入口
验证
因为Class文件并不是只能由Java源代码编译而来,键盘0/1就可以在二进制编辑器中敲出Class文件。验证字节码能够有效防止载入错误或恶意的字节码流而导致系统崩溃、收到攻击。
验证的四个阶段:
- 文件格式验证
- 元数据验证
- 字节码验证
- 符号引用验证
准备
为类变量(静态变量)分配内存并设置类变量的初始值;
例如一个类变量的定义如下:
public static int num = 12;
准备阶段结束后,num的值为0。
基本数据的初始值如下:
| 基本类型 | 初始值 |
|---|---|
| int | 0 |
| long | 0L |
| short | (short) 0 |
| boolean | False |
| byte | (byte) 0 |
| char | '\u0000' |
| double | 0.0d |
| float | 0.0f |
❗️特殊情况,当类变量为常量时,准备阶段后,此类变量的值被赋值为设定值。
public final static int num = 12;
准备阶段后,num的值为12。
解析
解析的对象:类/接口、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符。
这涉及符号引用和直接引用的逻辑,后续详解。
解析
解析的对象:类/接口、字段、类方法、接口方法、方法类型、方法句柄、调用点限定符。
这涉及符号引用和直接引用的逻辑,后续详解。
初始化
初始化阶段就是执行类构造器()方法的过程。()方法是Javac编译器自动生成的。
()方法由编译器自动收集类中所有类变量赋值和静态代码块的语句。
类加载器
在java虚拟机中,只存在两类加载器,启动类加载器和其他类加载器。
启动类加载器是由C++实现,其他类加载器由Java语言实现。