在 Java 中,类加载的流程有一个专门的机制叫做“类加载机制”。类加载机制是指一个类在 Java 虚拟机(JVM)中的履行流程,它也是 Java 程序能够正常履行的关键所在,那它的详细履行流程是啥?接下来我们一同来看。

流程概述

在 JVM 中,类加载会经历以下 5 个阶段:

  1. 加载阶段(Loading)
  2. 验证阶段(Verification)
  3. 预备阶段(Preparation)
  4. 解析阶段(Resolution)
  5. 初始化阶段(Initialization)

其间:验证阶段、预备阶段和解析阶段合起来又称为衔接阶段,所以以上 5 个阶段又能够划分为 3 大类:

  1. 加载阶段(Loading)
  2. 衔接阶段(Linking)
    1. 验证阶段(Verification)
    2. 预备阶段(Preparation)
    3. 解析阶段(Resolution)
  3. 初始化阶段(Initialization)

详细分类如下图所示:

类是如何加载的?
这 3 大类、5 个流程的详细履行细节是这样的。

1.加载阶段

简略来说,加载阶段就是将类文件加载到内存中的进程。在加载阶段,JVM 需求完结以下 3 件事:

  1. 通过一个类的全限定名来获取界说此类的二进制字节省;

  2. 将这个字节省所代表的静态存储结构转化为办法区的运行时数据结构;

  3. 在内存中生成一个代表这个类的 java.lang.Class 对象,作为办法区这个类的各种数据的拜访进口。

    2.衔接阶段

    衔接阶段又分为:验证阶段(Verification)、预备阶段(Preparation)和解析阶段(Resolution),详细履行的细节如下。

    2.1 验证阶段

    验证阶段也叫做校验阶段,它首要是用来验证加载到内存中的类是否是安全合规的文件,验证的首要动作大概有以下几个(当然,以下细节如果实在记不住也没关系):

  • 文件格局校验包含常量池中的常量类型、Class 文件的各个部分是否被删除或被追加了其他信息等;

  • 元数据校验包含父类正确性校验(检查父类是否有被 final 润饰)、抽象类校验等;

  • 字节码校验,此进程最为关键和杂乱,首要用于校验程序中的语义是否合法且符合逻辑;

  • 符号引证校验,对类本身以外比如常量池中的各种符号引证的信息进行匹配性校验。

    2.2 预备阶段

    预备阶段就开端给类中的静态变量设置默认值了,注意这里不是给静态变量设置初始值,而是设置默认值,二者还是有很大差异的。 举个比如,比如代码中写的内容是:

    public static int number = 10;

那么此时是给 number 变量设置的 int 值是默认值 0,而非初始值 10。

2.3 解析阶段

解析阶段就是将常量池中的符号引证更换成直接引证了,所谓的符号引证是指以一组符号来描绘所引证的方针,符号能够是任何方式的字面量,只要运用时能无歧义地定位到方针即可;而直接引证是能够直接指向方针的指针、相对偏移量或者是一个能间接定位到方针的句柄。 符号引证和直接引证有一个重要的差异:运用符号引证时被引证的方针不一定现已加载到内存中;而运用直接引证时,引证的方针必定现已存在虚拟机的内存中了。

3.初始化阶段

初始化阶段,Java 虚拟机真正开端履行类中编写的 Java 程序代码,将主导权移交给应用程序。到这一进程之后,类的加载进程就算正式完结了,此时会给静态变量设置初始值,并履行静态代码块的内容。

总结

类加载流程总共分为 3 大类,5 个首要流程:

  1. 加载阶段(Loading):将类文件加载到内存。
  2. 衔接阶段(Linking)
    1. 验证阶段(Verification):类文件安全性效验。
    2. 预备阶段(Preparation):给静态变量设置默认值。
    3. 解析阶段(Resolution):将符号引证转换为直接引证。
  3. 初始化阶段(Initialization):履行静态代码块和给静态变量设置初始值。

本文已收录到 Gitee 开源库房《Java 面试攻略》,其间包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计形式、消息行列等模块。Java 面试有它就够了,点击查看详情:interview: 400+ 道 Java 常见面试题和解析,继续更新中……