【JVM】类加载过程

类加载Class类型的文件主要三步:加载->链接->初始化。链接过程又可以分为三步:验证->准备->解析

全文的思维导图

image-20220106115102372

加载

类加载阶段主要完成如下三件事

  1. 通过全类名,获取定义此类的二进制字节流。
  2. 解析类的二进制流为方法区的数据结构。
  3. 在内存中创建一个代表该类的Class的对象,作为方法区这个类的访问入口。

该阶段可以大致如图所示:

链接

主要分为三个阶段:验证、准备、解析

验证

目的是确保加载的class文件的字节流中包含信息符合当前虚拟机的要求,运行时不会危害虚拟机的自身安全。

四种验证:文件格式验证,元数据验证,字节码验证,符号引用验证。

准备

主要是为类的静态变量分配内存,并初始化为默认初始值。即零值,这个0值是根据数据类型默认的0值,如果是boolean,则初始化为false。

如果类静态变量的字段属性表中存在constant Value属性,则直接执行赋值语句。

  1. 类静态变量为基本数据类型,并且被final修饰。
  2. 类静态变量为String类型,被final修饰,并且以字面量的形式赋值

下面我们用一个例子验证上面的说法:

/**
 * @author yanshuang
 * @date 2022/1/5 9:17 下午
 */
public class constantValueTest {
​
    private static int age = 10;
    private static final int length = 10;
    private static final String name = "zhangsan";
    private static final String s = new String("s");
​
}
​
复制代码

我们查看编译后的class文件字节码

image-20220106102901726

可以看到属性lengthname存在ConstantValue,并且在此阶段直接赋值。

image-20220106103147964

image-20220106103204815

解析

将类、方法、字段和方法的符号引用(在常量池中)转为直接引用。

符号引用:用一组符号来描述所引用的目标

直接引用:直接指向目标的指针

初始化

执行类静态成员赋值语句和静态代码块中的语句。

执行类构造方法

测试

/**
 * @author yanshuang
 * @date 2022/1/6 10:40 上午
 */
public class clinitTest {
​
    private String name;
    private int age = 10;
    private static int gender = 1;
​
    {
        System.out.println("构造代码块");
    }
​
    static {
        System.out.println("静态代码块");
    }
​
    public clinitTest () {
        System.out.println("构造方法");
    }
​
    public String getName() {
        return this.name;
    }
}
​
复制代码

可以看到字节码中包含了3个方法,getName我们都知道,那么和方法里面执行了哪些逻辑?image-20220106105102056

从字节码角度分析一下:

方法: image-20220106105156170

从字节码可以看到方法的主要逻辑为

  1. 调用父类的方法
  2. 非静态成员变量赋值
  3. 执行构造代码块
  4. 执行构造函数

方法 image-20220106105437000

从字节码可以看到方法的主要逻辑为

  1. 执行静态方法的赋值语句
  2. 执行静态代码块中的语句
  3. 需要注意一点是,Java虚拟机会保证子类的方法执行前,父类的方法已经执行完毕

静态代码块,构造方法,构造函数的执行顺序?

没有继承关系情况的执行顺序

  1. 静态代码块和静态成员变量,执行顺序由编写顺序决定(只会执行一次)
  2. 构造代码块和非静态成员变量,执行顺序由编写顺序决定。
  3. 构造函数

有继承情况的执行顺序

  1. 父类的静态(静态代码块,静态成员变量),子类的静态(静态代码块,静态成员变量)
  2. 父类的非静态(构造代码块,非静态成员变量),父类的构造方法
  3. 子类的非静态(构造代码块,非静态成员变量),子类的构造方法

猜你喜欢

转载自juejin.im/post/7049945409438875678