JVM的类加载过程

JVM的类加载分为5个阶段:

加载、验证、准备、解析、初始化。

在类初始化完成后就可以使用该类的信息,在一个类不再被需要时可以从JVM中卸载,如图1所示。
在这里插入图片描述

1.加载

指JVM读取Class文件,并且根据Class文件描述创建java.lang.Class对象的过程。类加载过程主要包含将Class文件读取到运行时区域的方法区内,在堆中创建java.lang.Class对象,并封装类在方法区的数据结构的过程,

在读取Class文件时既可以通过文件的形式读取,也可以通过jar包、war包读取,还可以通过代理自动生成Class或其他方式读取。

什么是方法区?

2.验证

主要用于确保Class文件符合当前虚拟机的要求,保障虚拟机自身的安全,只有通过验证的Class文件才能被JVM加载。

3.准备

主要工作是在方法区中为类变量分配内存空间并设置类中变量的初始值。初始值指不同数据类型的默认值,这里需要注意final类型的变量和非final类型的变量在准备阶段的数据初始化过程不同。比如一个成员变量的定义如下:

public static long value=1000

在以上代码中,静态变量value在准备阶段的初始值是0,将value设置为1000的动作是在对象初始化时完成的,因为JVM在编译阶段会将静态变量的初始化操作定义在构造器中。但是,如果将变量value声明为final类型:

public static final int value=1000

则JVM在编译阶段后会为final类型的变量value生成其对应的ConstantValue属性,虚拟机在准备阶段会根据ConstantValue属性将value赋值为1000。

4.解析

JVM会将常量池中的符号引用替换为直接引用。

什么是常量池?

5.初始化

主要通过执行类构造器的<client>方法为类进行初始化。方法是在编译阶段由编译器自动收集类中静态语句块和变量的赋值操作组成的。JVM规定,只有在父类的方法都执行成功后,子类中的方法才可以被执行。在一个类中既没有静态变量赋值操作也没有静态语句块时,编译器不会为该类生成方法。

在发生以下几种情况时,JVM不会执行类的初始化流程。

什么是<client>方法?

◎ 常量在编译时会将其常量值存入使用该常量的类的常量池中,该过程不需要调用常量所在的类,因此不会触发该常量类的初始化。
◎ 在子类引用父类的静态字段时,不会触发子类的初始化,只会触发父类的初始化。◎ 定义对象数组,不会触发该类的初始化。
◎ 在使用类名获取Class对象时不会触发类的初始化。
◎ 在使用Class.forName加载指定的类时,可以通过initialize参数设置是否需要对类进行初始化。
◎ 在使用ClassLoader默认的loadClass方法加载类时不会触发该类的初始化。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值