Java的类加载过程可以分为三个主要阶段:加载(Loading)、链接(Linking)和初始化(Initialization)。链接阶段又可以细分为验证(Verification)、准备(Preparation)和解析(Resolution)三个步骤。具体如下
内加载过程是一个非常常见的面试题
-
加载(Loading):
- 类加载器(ClassLoader)负责找到对应的类文件(.class文件),然后读取这个类的二进制数据。
- 类加载器将这个二进制数据加载到内存中,创建一个java.lang.Class对象来表示这个类。
- Java有三种常见类加载器:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和系统类加载器(System ClassLoader)。
-
链接(Linking):
- 验证(Verification):确保加载的类信息符合Java虚拟机规范,没有安全方面的问题。
- 准备(Preparation):为类的静态变量分配内存,并设置默认初始值。注意,这里只是设置了静态变量的默认值,并没有进行初始化。
- 解析(Resolution):将符号引用替换为直接引用的过程。符号引用是一组符号来描述目标,可以是任何字面量。直接引用则是直接指向目标的指针、相对偏移量或间接定位到目标的句柄。
-
初始化(Initialization):
- 初始化阶段是类加载过程的最后一步。在这个阶段,类加载器会执行类的初始化方法(
<clinit>()
),该方法由编译器自动生成,用于初始化类的静态变量和执行静态代码块。 <clinit>()
方法的执行顺序是按照源代码中静态变量和静态代码块的顺序执行的。- 一旦
<clinit>()
方法执行完毕,类就被完全加载并准备好被使用了。
- 初始化阶段是类加载过程的最后一步。在这个阶段,类加载器会执行类的初始化方法(
这个过程确保了类的类型安全,并且保证了类在第一次被使用时才被加载和初始化,从而实现了懒加载。这种机制有助于提高程序的启动性能,因为只有当实际需要使用某个类时,才会去加载它。
下面是网上的JVM体系图,左下角的棕色的部分就是内加载器放大的详细内容。
以上是类加载的过程,类加载使用之后的部分