一、前言

  前面分析了class文件具体含义,接着需要将class文件加载到虚拟机中,这个过程是怎样的呢,下面,我们来仔细分析。

二、什么是类加载机制

  把class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是类加载机制。

三、类加载总体流程图

  【JVM】JVM系列之类加载机制(四)

  说明:类的整个生命周期分为以上七个阶段,验证、准备、解析统称为连接阶段。关于加载流程笔者之前也写过一篇文章JVM之类加载器,从代码层面了解类加载机制。下面我们将更加详细的讲解各个阶段,加载阶段只是类加载的一个步骤,类加载包括以上的七个步骤。

四、何时进行类加载

  加虚拟机规范规定了如下几种情况就必须要进行初始化(开始类加载)。

  1.  遇到new、getstatic、putstatic、invokestatic指令时,对应到程序中就是使用到new实例化对象时、读取或设置类静态字段时(非final)、调用静态方法时。需要进行初始化。

  2. 使用java.lang.reflect包的方法对类进行反射调用时,需要进行初始化。

  3. 使用一个类时,若其父类还未初始化,则需先初始化其父类。

  4. 虚拟机启动时,包含main方法的类,虚拟机会将其初始化。

  5. java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic方法句柄,并且这个方法句柄对应的类没有进行初始化,则需要先进行初始化。

  以上五种情况称为主动使用,其他的情况均称为被动使用,被动使用不会导致初始化。

五、初始化示例说明

  1. 对于类而言,使用父类的静态字段(非final)不会导致子类的初始化。  

class SuperClass {
    static {
        System.out.println("super");
    }
    
    public static final int value = 123;
}

class SubClass extends SuperClass {
    static {
        System.out.println("sub");
    }
}

public class TestInit {
    public static void main(String[] args) {
        System.out.println(SubClass.value);
    }
}
View Code

相关文章: