在Java虚拟机(JVM)中,类加载过程是将编译后的.class
文件或其它格式的类定义数据加载到JVM内存的方法区,并为这些类型创建运行时的Class对象实例的过程。这个过程确保了Java代码能够在JVM上被正确执行。类加载主要包括以下几个步骤:
-
加载(Loading)
- 通过类的全限定名来查找和读取对应的二进制字节流(即.class文件)。
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
- 在内存中生成一个代表该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
-
验证(Verification)
- 确保被加载的类信息符合JVM规范,没有安全方面的问题,如非法的数据类型、不合法的操作指令等。
- 检查类文件结构、元数据、字节码、符号引用是否正确无误。
-
准备(Preparation)
- 为类的静态变量分配内存并初始化为默认值(对于非final static变量来说,这里的初始化仅仅是分配空间但不赋予具体值)。
- 对于final static类型的变量,如果其值在编译时已知,则会在此阶段直接赋值。
-
解析(Resolution)
- 将常量池中的符号引用替换为直接引用(比如方法区内的指针或者偏移量),使得能够快速定位到方法表、字段表及接口方法表等。
-
初始化(Initialization)
- 如果类还没有被初始化过,那么执行类构造器
<clinit>
方法的过程。此方法由编译器自动收集类中所有静态变量的赋值动作和静态语句块合并产生的。 - 初始化阶段是真正执行类中静态初始化器(static initializer blocks)和静态变量赋值操作的时候。
- 如果类还没有被初始化过,那么执行类构造器
-
使用(Using)
- 类被JVM实际使用,在堆上创建对象实例,调用类的方法等。
-
卸载(Unloading)
- 当一个类不再被任何线程引用时,经过垃圾回收机制确认后,类加载器可以卸载这个类,释放它占用的方法区资源。
在类加载过程中,还有一个重要的概念是类加载器(ClassLoader),它负责加载类的具体工作,且遵循特定的委托加载机制(如双亲委派模型),确保类加载的统一性与安全性。