4 类的生命周期
4 类的生命周期
类的生命周期描述了一个类加载、使用、卸载的整个过程
类的生命周期包括五个阶段:加载、连接、初始化、使用、卸载
-
加载
- 加载阶段第一步是类加载器根据类的全限定名通过不同的渠道(本地文件、动态代理生成等)以二进制流的方式获取字节码信息
- 类加载器在加载完类之后,java虚拟机会将字节码中的信息保存到方法区中。生成一个InstanceKlass对象,保存类的所有信息,里边还包含实现特定功能,比如:多态的信息
- java虚拟机还会在堆中生成一份与方法区中数据类似的java.lang.Class对象,静态字段会保存在堆中(JDK1.8以后)
- 在堆中生成的Class对象的好处:开发者不需要去访问方法区,访问Class对象即可,方法区中的信息更多
-
连接
-
验证
验证内容是否符合jvm规范
-
准备
给静态变量赋初始值,不是给它赋自己定义的值
例如:
public static int i = 2;
,在准备阶段的时候,栈中的i的值赋予了初始值0,还没有赋值2但如果是用了
final
修饰,在准备阶段就直接赋了自己定义的值。 -
解析
将常量池中的符号引用替换成指向内存的直接引用
-
-
初始化(重要,程序员可以干涉)
-
初始化阶段会执行静态代码块中的代码,并为静态变量赋值
-
初始化阶段会执行字节码文件中的
clinit
部分的字节码指令 -
以下几种方式会导致类的初始化:
- 1.访问一个类的静态变量或者静态方法,注意变量是final修饰的并且等号右边是常量不会触发初始化
- 2.调用Class.forName(String className)
- 3.new一个该类的对象时
- 4.执行Main方法的当前类
例:
public class Test2 { public static void main(String[] args) { System.out.println("A"); new Test2(); new Test2(); } public Test2(){ System.out.println("B"); } { System.out.println("C"); } static { System.out.println("D"); } } //输出结果为: D A C B C B
-
以下几种情况不会初始化
- 1.无静态代码块且无静态变量赋值语句
- 2.有静态变量的声明,但是没有赋值语句
- 3.静态变量的定义使用final关键字,这类变量会在准备阶段直接进行初始化
-
父类和子类的初始化
- 直接访问父类的静态变量,不会触发子类的初始化子类的
- 初始化
clinit
调用之前,会先调用父类的clinit
初始化方法
-
数组的创建不会导致数组中元素的类进行初始化
//数组的创建不会导致数组中元素的类进行初始化 public class TestArrayInit { public static void main(String[] args) { TestArrayInit_A[] arr = new TestArrayInit_A[10]; } } class TestArrayInit_A { static { System.out.println("TestArrayInit_A的静态代码块运行"); } }
- final修饰的变量如果赋值的内容需要执行指令才能得出结果,会执行
clinit
方法进行初始化
public class TestFinalInit { public static void main(String[] args) { System.out.println(TestFinalInit_A.a); } } class TestFinalInit_A{ public static final int a = Integer.valueOf(1); static { System.out.println("静态代码块运行了"); } } //输出结果: 静态代码块运行了 1
-
-
结合类连接和初始化阶段思考以下两个案例:
public class HSDBDemo { static { i = 10; } public static int i=2; public static void main(String[] args) throws IOException { HSDBDemo hsdbDemo = new HSDBDemo(); //输出结果位2 System.out.println(i); } }
public class HSDBDemo { static { i = 10; } public static int i; public static void main(String[] args) throws IOException { HSDBDemo hsdbDemo = new HSDBDemo(); //输出结果为10 System.out.println(i); } }
-
使用
-
卸载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署