目录
- 1- 引言:类加载的执行过程
- 1-1 类加载的执行过程是什么?(What)
- 2- ⭐核心:详解类加载的执行过程(How)
- 2-1 加载——>加载到运行时数据区
- 2-2 验证——>类的安全性检查
- 2-3 准备——>为类变量分配内存并设置初始值
- 2-4 解析——>把类中的符号引用转为直接引用
- 2-5 初始化——>对静态变量和静态代码块进行初始化
- 2-6 使用
- 2-7 卸载
- 3-小结
- 3-1 类装载的执行过程
1- 引言:类加载的执行过程
1-1 类加载的执行过程是什么?(What)
- 类从加载到虚拟机中开始,直到卸载为止,它的整个生命周期包括了:①加载、②验证、③准备、④解析、⑤初始化、⑥使用和 ⑦卸载这 7 个阶段。其中,验证,准备和解析这三个部分统称为连接(linking)
2- ⭐核心:详解类加载的执行过程(How)
2-1 加载——>加载到运行时数据区
- 通过类的全民,获取类的二进制数据流
- 解析类的二进制数据流为方法区内的数据结构(Java类模型)
- 创建 java.lang.Class 类的实例,表示该类型。作为方法区这个类的各种数据的访问入口
举例说明
- 假设现在有一个
Person
类,当Person
类被加载之后就会存到 JVM 的运行时数据区,主要涉及运行时数据区的两个部分进行存储。- ① 方法区/元空间:存储的是这个类的信息,比如 Person 类的构造函数、方法、字段等信息。其实就是目前的元空间
- ② 堆:堆中会开辟一段空间去存储当前类的 Class 对象,用于创建具体的 Class 对象时使用。比如此时创建了两个实例对象 ,此时这两个实例对象的对象头都会指向当前这个 Class 对象。但具体的类的构造函数、方法、字段等信息,需要到方法区中去获取,此时堆中的 Class 对象就可以找到方法区中的的这些类信息。
2-2 验证——>类的安全性检查
- ①主要是格式检查,检查文件格式是否错误、语法是否错误、字节码是否合规
- ②符号引用验证:Class文件在其常量池会通过字符串记录自己将要使用的其他类或方法,检查他们是否存在
验证主要负责检查类是否符合 JVM 规范
- (1)文件格式验证
- (2)元数据验证
- (3)字节码验证
- (4)符号引用验证
2-3 准备——>为类变量分配内存并设置初始值
准备阶段主要是对类的变量进行复制,也就是带有 static 关键字的变量。赋值情况主要分为以下三种
- ① static 变量,分配空间在准备阶段完成(设置默认值),赋值在初始化阶段完成
- 比如
static int b = 10
赋默认值是 0 ,在初始化阶段才赋值为 10
- 比如
- ② static 变量是 final 的基本类型,以及字符串常量,值已经确定,赋值在准备阶段完成
- 比如 下面代码中的变量 c 和 d ,带了 final 修饰符,此时在准备阶段就完成了赋值
- ③ static 变量是 final的 引用类型,那么赋值也会在初始化阶段完成
- 比如
static final Object obj = new Object()
,其中 Object 是引用数据类型,因此在初始化阶段才会完成赋值
- 比如
public class Application {static int b = 10;static final int c = 20;static final String d = "hello";static final Object obj = new Object();
}
2-4 解析——>把类中的符号引用转为直接引用
比如:方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接指向方法。
- 符号引用(Symbolic Reference):这是一种抽象的引用形式,使用一组符号来描述所引用的目标。它可以是任何形式的字符串描述,如完全限定名、方法名称和描述符组合等。符号引用并不直接指向对象在内存中的地址。
- 直接引用(Direct Reference):这是转换后的引用,直接指向目标的内存地址或者对目标的直接指针。直接引用是在解析阶段生成的,当符号引用被第一次使用时,它会被转换为直接引用。
解析是指将类文件中的符号引用转换为直接引用的过程。这个转换过程是 JVM 执行的一部分,确保了程序的执行效率和安全性。
2-5 初始化——>对静态变量和静态代码块进行初始化
- 如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。
- 如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。
- 如果通过子类访问父类的静态变量,则此时只会初始化父类的静态变量,而不会初始化子类。
2-6 使用
JVM 开始从入口方法开始执行用户的程序代码
- 调用静态类的成员信息(比如:静态字段、静态方法)
- 使用 new 关键字为其创建对象实例
2-7 卸载
- 就是说当用户程序代码执行完毕之后, JVM 就开始销毁创建的 class 对象了,这时候就相当于把类已经给卸载了。