Java虚拟机是如何加载Java类的?

从 class 文件到内存中的类,按先后顺序需要经过加载、链接以及初始化三大步骤。其中,链接过程中同样需要验证;而内存中的类没有经过初始化,同样不能使用。

1.加载

java语言主要分为两大类型:基本类型引用类型

  1. 基本类型有:byte(位:最大存储数据量255)、short(短整型:最大数据存储量是65536)、int(整型:最大数据存储量是65536)、long(长整型:最大数据存储量是65536)、float(单精度类型)、double(双精度类型)、boolean(布尔型)、char(字符型)基本类型是虚拟机事先定义好的。
  2. 引用类型:类、接口、数组类和泛型参数。由于泛型参数会在编译过程中被擦除,因此 Java 虚拟机实际上只有前三种。数组类是由 Java 虚拟机直接生成的,其他两种则有对应的字节流。

加载,是指查找字节流,并且据此创建类的过程。

2.链接

链接,是指将创建成的类合并至 Java 虚拟机中,使之能够执行的过程。它可分为验证准备以及解析三个阶段。

  1. 验证阶段的目的,在于确保被加载类能够满足 Java 虚拟机的约束条件。
  2. 准备阶段的目的,则是为被加载类的静态字段分配内存。
  3. 解析阶段的目的,正是将这些符号引用解析成为实际引用。如果符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化。)

3.初始化

类的初始化是指在首次使用该类之前对类进行设置和准备的过程。

  1. 静态变量的初始化:静态变量在类加载的时候进行初始化,只会初始化一次。可以通过静态代码块或者直接赋值的方式进行初始化。
  2. 静态代码块的执行:静态代码块中的代码在类加载时执行,可以用来初始化静态变量或者执行其他一次性的操作。
  3. 实例变量的初始化:实例变量在创建对象时进行初始化,默认会赋予默认值,也可以在构造方法中进行初始化。
  4. 构造方法的执行:构造方法会在创建对象时执行,用于完成对象的初始化操作。

在类的初始化过程中,会按照顺序依次执行静态变量的初始化和静态代码块的内容。然后根据需要创建对象时,会执行相应的实例变量初始化和构造方法。需要注意的是,类的初始化只会在第一次使用该类时进行,以后再使用该类时就不会再进行初始化操作了。

JVM 规范枚举了下述多种触发情况:

  • 当虚拟机启动时,初始化用户指定的主类;
  • 当遇到用以新建目标类实例的 new 指令时,初始化 new 指令的目标类;
  • 当遇到调用静态方法的指令时,初始化该静态方法所在的类;
  • 当遇到访问静态字段的指令时,初始化该静态字段所在的类;
  • 子类的初始化会触发父类的初始化;
  • 如果一个接口定义了 default 方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化;
  • 使用反射 API 对某个类进行反射调用时,初始化这个类;
  • 当初次调用 MethodHandle 实例时,初始化该 MethodHandle 指向的方法所在的类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值