## JVM 的类加载过程？

Java 中的类加载过过程分为三个阶段：
- 加载
- 链接
  - 验证
  - 准备
  - 解析 
- 初始化

## 这三个阶段怎么理解？

- 加载阶段：
      查找并加载类的二进制数据（网络、jar 包、运行时生成等）。将类的 `.class`文件中的二进制数据读入内存当中。将其放在方法区中，然后创建一个`java.lang.Class`对象（存放于堆中）用于封装类在方法区的数据结构。
- 链接阶段：
      Java 类加载器对类进行验证、准备（分配内存、初始化默认值）和解析操作，将类与类之间的关系确定好（**符号引用转直接引用**），然后校验字节码。
  - 验证：验证文件格式、元数据、字节码、二进制兼容性是否正确
  - 准备：给类的静态变量分配内存，初始化为默认值。
  - 解析：把类的符号引用转为直接引用
 
- 初始化阶段：
      类加载过程的最后一步，初始化阶段是执行类构造器中`<clinit> ()`方法的过程。这里利用了一种懒加载的思想，所有 Java 虚拟机实现必须在每个类或者接口被 Java 程序首次主动使用才初始化。



## 知识扩展

什么是符号引用和直接引用？

**符号引用：** 是一种直接表示引用目标的符号名称。例如：类名、字段名、方法名等。符号引用和实际的内存地址无关，符号引用只是一个标识符。用于描述被引用者，也就是类似于变量名的东西。符号引用产生于编译期，存储于`Class`文件。
**直接引用：** 是实际指向目标的内存地址。例如：类的实例、方法的字节码等。直接引用与内存地址直接相关，产生于运行期。

说白了，符号引用就相当于一个变量名；直接引用就相当于内存地址。
