JVM学习笔记(四)类加载的过程

通过之前的学习,我们知道:类加载就是根据一个类的全限定名,将其字节码文件 加载到JVM内部,并创建java.lang.Class对象实例。其实,一个类的加载过程应包括:加载,连接(验证,准备,解析),初始化
在这里插入图片描述
加载:
通过类加载器,根据一个类的全限定名,将该类的字节码文件加载到JVM中(存储在方法区内),再创建java.lang.Class对象实例,由于JVM规范中并没有要求Class对象实例应该是否应该存放在堆区中,在HotSpot VM中将Class对象实例存储在方法区内。该方法区中的Class对象实例,就会作为日后访问该类数据的入口。

连接:
连接是将JVM中的二进制字节流的类数据信息合并到JVM的运行时状态中。连接阶段又是由:验证,准备,解析 3个阶段组成。

  1. 验证:主要任务是验证类的数据信息是否符合JVM的规范,是否是一个有效的字节码文件;
  2. 准备:主要是给类中的静态变量分配内存空间,并赋初始值;
  3. 解析:主要任务是将常量池中的所有符号引用变成直接引用;

注意:Java虚拟机中并没有明确要求解析阶段必须得在初始化之后,因此可以先进行类的初始化阶段,在进行解析阶段。

初始化:
该阶段中,JVM会把程序中所有标识static关键字的语句全部执行一遍,会覆盖在连接的准备阶段所赋的初始值,在初始化阶段 JVM还会执行static块中的所有操作。

/

小总结:类的加载总共包含三个阶段:加载,连接,初始化。

  1. 加载:由类加载器根据类的全限定名,采用双亲委派机制将类的字节码文件加载进JVM中,并创建Class实例对象。
  2. 连接:该阶段主要是将,加载进JVM中的二进制字节流数据的类信息合并到JVM的运行时中来,其中包括三个阶段:
    验证:检查类的数据信息是否满足JVM的规定,以及二进制字节码文件是否满足规定;
    准备:给类中的static静态变量分配内存空间,并赋初始值;
    解析:将常量池中的所有符号引用全部变成直接引用。
  3. 初始化:执行类中的所有static语句,也包括static块。

/
初始化操作的时机选择:
Java虚拟机对加载和连接的时机选择有很大的灵活性,但是对于初始化,却有着规范限制,一个类或者接口应该在第一次主动使用时完成初始化操作,具体包括:

  1. 在给一个类创建新对象时:包括new,反射,序列化。
  2. 调用一个的静态方法时;
  3. 调用Java API中的反射方法时;
  4. 初始化一个派生类时(其超类必须已经完成初始化操作)接口中并不适合 因为当调用超接口的非静态字段时 必须完成初始化操作;
  5. JVM启动包含main方法的类时;
  6. 调用一个类或者接口的静态字段时,并给这些静态字段进行赋值操作;

Guess you like

Origin blog.csdn.net/jingli456/article/details/112985483
Recommended