文章目录
- 🍔类的生命周期概述
- ⭐加载
- ⭐连接
- ⭐初始化
- ⭐类的卸载
🍔类的生命周期概述
Java类的生命周期包括加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Usage)和卸载(Unloading)等阶段。
加载(Loading):将类的字节码文件加载到内存中。加载过程可以通过类加载器(ClassLoader)来完成,包括以下步骤:
- 加载:根据类的全限定名找到对应的字节码文件,并读取到内存中。
- 验证:验证字节码的合法性、安全性等,确保符合Java虚拟机规范。
- 准备:为类的静态变量分配内存空间,并设置默认初始值。
- 解析:将符号引用转换为直接引用,如将方法调用转换为具体的方法实现。
验证(Verification):验证加载的字节码的正确性和安全性,包括以下方面:
- 文件格式验证:检查字节码文件是否符合Class文件格式规范。
- 元数据验证:检查类的元数据信息是否正确。
- 字节码验证:检查字节码是否合法、类型是否匹配等。
- 符号引用验证:检查符号引用是否有效。
准备(Preparation):为类的静态变量分配内存,并设置默认初始值。这些静态变量会被存储在方法区中的静态变量区域。
解析(Resolution):将类的符号引用转换为直接引用,包括以下方面:
- 类或接口解析:将类或接口的符号引用转换为对应的直接引用。
- 字段解析和方法解析:将字段或方法的符号引用转换为对应的直接引用。
初始化(Initialization):初始化阶段是类生命周期中的重要阶段。在该阶段,虚拟机会执行类的初始化代码,包括静态变量的赋值和静态代码块的执行。初始化是按需进行的,即在首次使用类时才会触发。
使用(Usage):在类初始化完成后,可以通过创建对象、调用方法等方式来使用类。
卸载(Unloading):当类不再被引用,并且没有任何活动实例时,类加载器可以卸载该类,释放内存空间。
⭐加载
类加载器
根据类的全限定名通过不同的渠道以二进制流的方式获取字节码信息
2.类加载器加载完后,Java虚拟机会将字节码的信息保存到方法区
中,生成一个InstanceKlass对象,保存类的所有信息,里面还包含带实现特定功能比如多态的信息
3.同时,Java虚拟机还会在堆区中生成一份和方法区中的数据类似的java.lang.Class对象
作用是在Java代码中去获取类的信息和存储静态字段的数据
⭐连接
主要分为下面三个阶段:
- 验证
文件格式验证:检查字节码文件是否符合Class文件格式规范。
元数据验证:检查类的元数据信息是否正确。
字节码验证:检查字节码是否合法、类型是否匹配等。
符号引用验证:检查符号引用是否有效。
- 准备
为静态变量分配内存并且设置初值(注意不是初始值)
如果是final修饰,准备阶段会将代码中的值进行赋值
- 解析
将常量池中的符号引用替换为直接引用
⭐初始化
- 初始化阶段会执行
静态代码块的代码
,并且为静态变量赋值
- 初始化阶段会执行字节码文件中
clinit
部分的字节码指令
静态变量的定义使用final关键字,这类变量会在
准备阶段直接进行初始化
(除非要执行方法)
直接访问父类的静态变量,不会触发子类的初始化,子类的初始化cinit在调用之前,会先调用父类的cinit初始化方法
⭐类的卸载
判断一个类是否可以被卸载,需要同时满足下面三个条件
- 此类所有的实例对象都被回收,堆中不存在任何该类的实例对象以及子类对象
- 加载该类的类加载器以及被回收
- 该类对应的java.lang.Class对象没有在任何地方被引用
在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!