一个类型(在Java中通常指的是类或接口)从被加载到Java虚拟机(JVM)内存中开始,到最终从内存中卸载为止,其整个生命周期会经历以下阶段(其中验证、准备、解析三个部分统称为连接(Linking)):
- 加载(Loading):
- JVM通过类加载器(ClassLoader)查找类的二进制数据(.class文件),并将这些数据读入内存,转换为方法区内的运行时数据结构。同时,为该类型创建一个Class对象。
- 验证(Verification):
- JVM对加载的类数据进行合法性校验,确保符合Java虚拟机规范。验证包括文件格式验证、元数据验证、字节码验证以及符号引用验证等环节,以确保类的正确性和安全性。
- 准备(Preparation):
- JVM为类的静态变量分配内存,并初始化为默认值。对于基本类型,如int、float等,初始化为0或null;对于引用类型,初始化为null。
- 解析(Resolution):
- 将类型中引用的符号引用(如类、接口、字段和方法的全限定名)转换为直接引用(如内存地址),以便后续调用时能快速定位到具体的方法或字段。
- 初始化(Initialization):
- 执行类的初始化方法
<clinit>
,这个方法是由编译器自动收集类中所有静态变量的赋值动作和静态初始化块中的语句合并产生的。初始化阶段是真正执行类中静态初始化代码的阶段。
- 使用(Use):
- 类被加载、验证、准备和初始化后,便可以被应用程序使用了。创建对象实例,调用方法,访问字段等操作都在这个阶段进行。
- 卸载(Unloading):
- 当一个类不再被任何线程引用,且满足垃圾回收的相关条件时,JVM会在适当的时候卸载该类,释放其在方法区所占用的空间。这个过程相对较少见,因为通常类加载后,其Class对象会一直存在于方法区中直到程序结束。
这七个阶段的发生顺序如下图所示:
请注意,类加载器的实现决定了类的加载行为和类加载的生命周期,包括类加载时机的选择以及类卸载的条件。在大多数实际应用中,类的生命周期会贯穿整个Java应用程序运行期间,除非应用程序执行环境(如服务器容器)支持动态加载和卸载类的功能。