Java类和对象的生命周期
类的生命周期
加载
将字节码文件读入内存中,转换为元空间的数据结构,包括类的元信息,并在堆中创建一个Class对象作为访问方法区数据的入口。
验证
确保字节码文件的合法性,
文件格式验证
元数据验证
字节码验证
符号引用验证
准备
为类的静态变量(static 修饰)分配内存,并设置默认初始值(如 int 为 0,boolean 为 false,引用类型为 null)。
解析
将类中的符号引用(如代码中引用的类名、方法名)转换为直接引用(内存地址)。
初始化
执行类的初始化代码(如静态变量的赋值语句、静态代码块 static {})。
初始化顺序:父类静态代码 → 子类静态代码;多个静态代码块按定义顺序执行。
触发时机:首次主动使用类时(如创建对象、调用静态方法、访问静态变量等)
使用
类的 Class 对象被回收,方法区中该类的元数据被清除。
卸载
卸载条件严格:该类的所有实例已被回收,加载该类的类加载器已被回收,且 Class 对象没有被任何地方引用。
一般情况下,系统类(如 java.lang.String)不会被卸载,自定义类在满足条件时可能被卸载。
对象的生命周期
创建
分配内存:在堆中为对象分配内存(取决于对象大小)。
初始化零值:为对象的实例变量设置默认初始值(同类的准备阶段,如 int 为 0)。
设置对象头:
存储对象的哈希码、
GC 分代年龄、
锁状态等信息。
执行实例初始化:先执行父类的实例代码块和构造方法,再执行子类的实例代码块和构造方法,完成变量赋值和初始化逻辑。
使用
对象被引用(如赋值给变量、作为参数传递等),处于可达状态。
可以调用其方法、访问字段,直到不再被任何引用指向。对象不再被任何活跃的引用变量指向(如引用变量被赋值为 null、超出作用域等),成为垃圾回收的候选对象。此时对象仍在堆中,尚未被回收。
回收
对象彻底从内存中消失,生命周期结束。
验证
public class BlockDemo { // 静态代码块 static {
System.out.println("静态代码块执行");
} // 实例代码块 {
System.out.println("实例代码块执行");
} public BlockDemo() { System.out.println("构造方法执行");
} public static void main(String[] args) { System.out.println("创建第一个对象:"); new BlockDemo(); System.out.println("\n创建第二个对象:"); new BlockDemo();
} }
public class ClassLifecycleDemo { // 静态代码块(类初始化时执行) static { System.out.println("ClassLifecycleDemo 静态代码块执行(类初始化)"); } // 实例代码块(对象创建时执行) { System.out.println("ClassLifecycleDemo 实例代码块执行(对象初始化)"); } // 构造方法 public ClassLifecycleDemo() { System.out.println("ClassLifecycleDemo 构造方法执行"); } public static void main(String[] args) throws Exception { System.out.println("=== main方法开始 ==="); // 情况1:仅获取Class对象(不触发初始化) Class<?> clazz = ClassLifecycleDemo.class; System.out.println("获取Class对象后,未创建实例"); // 情况2:首次主动使用类(创建实例,触发初始化) System.out.println("\n=== 首次创建实例 ==="); new ClassLifecycleDemo(); // 情况3:再次创建实例(类已初始化,不再执行静态代码块) System.out.println("\n=== 再次创建实例 ==="); new ClassLifecycleDemo(); } }
浙公网安备 33010602011771号