Java类加载原理

Posted by KANG's BLOG on Friday, March 10, 2023

类加载的时机

类的完整生命周期分为如下步骤:

flowchart LR
load(加载)-->verification(验证)-->preperation(准备)-->resolution(解析)-->initialization(初始化)-->using(使用)-->unloading(卸载)

classDef circle1 fill:#3e93ef, stroke:#3e93ef, color: #fff;
classDef circle2 fill:#ff8a00, stroke:#ff8a00, color: #fff;

load:::circle1
verification:::circle1
preperation:::circle1
initialization:::circle1
unloading:::circle1
resolution:::circle2
using:::circle2

其中加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,而Java为了支持“动态绑定”,解析有可能在初始化之后。

至于什么时候加载,《Java虚拟机规范》中没有强制约束,但严格规定了有且只有六种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要在此之前开始):

  1. 初始化对象和使用静态方法或静态属性
  2. 反射调用类的时候
  3. 子类被初始化的时候,父类需要先初始化(父子接口之间没有限制)
  4. 执行主类(包含main()方法的那个类)
  5. 如果一个java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四种类型的方法句柄,并且这个方法句柄对应的类没有进行过初始化,则需要先触发其初始化
  6. 如果接口中含有默认方法,在起实现类初始化前,要先初始化该接口