Java 类的加载过程是由 Java 虚拟机(JVM)负责执行的,主要分为加载、链接(验证、准备、解析)、初始化这几个步骤。下面详细介绍每个阶段的内容:
1. 加载(Loading)
在加载阶段,JVM 需要完成以下三件事情:
- 通过类的全限定名获取定义该类的二进制字节流。这通常是从文件系统中的
.class
文件读取,但也可能从网络、数据库等其他来源获取。 - 将这个字节流代表的静态存储结构转化为方法区运行时数据结构。
- 在内存中生成一个代表该类的
java.lang.Class
对象,作为方法区这个类的各种数据访问入口。
2. 链接(Linking)
链接阶段又细分为三个子步骤:验证、准备和解析。
2.1 验证(Verification)
目的是确保被加载的类的正确性,包括文件格式验证、元数据验证、字节码验证以及符号引用验证等,以保证不会危害到 JVM 的安全。
2.2 准备(Preparation)
为类变量分配内存,并设置默认初始值。需要注意的是这里并不包含用 final
修饰的基本类型或字符串常量,这些会在 Javac 编译期间就放入常量池中,并在准备阶段直接赋值。
2.3 解析(Resolution)
将类、接口、字段和方法的符号引用转为直接引用的过程。符号引用是以一组符号来描述所引用的目标,而直接引用可以直接指向目标的指针、相对偏移量或者是一个能间接定位到目标的句柄。
3. 初始化(Initialization)
这是类加载的最后一步,根据程序员通过程序制定的主观计划去初始化类变量和其他资源。也就是说,执行类构造器 <clinit>()
方法的过程。在这个过程中,会执行静态代码块以及静态成员变量的初始化操作。
类加载器
Java 提供了三种类型的类加载器:
- 启动类加载器(Bootstrap Class Loader):负责加载存放在
<JAVA_HOME>\lib
目录下的核心类库,或者被-Xbootclasspath
参数指定的路径中的类库。 - 扩展类加载器(Extension Class Loader):负责加载
<JAVA_HOME>\lib\ext
目录下的 jar 包及被java.ext.dirs
系统变量所指定的路径中的所有类库。 - 应用程序类加载器(Application Class Loader):也称为系统类加载器,它负责加载用户类路径(ClassPath)上的所有类库,一般我们自己写的代码以及第三方 jar 包都是由这个类加载器加载的。
此外,还可以自定义类加载器来满足特定需求。
了解 Java 类加载机制对于理解 Java 程序的工作原理至关重要,特别是在处理复杂的依赖关系、热部署以及安全管理等方面。
THE END