Java虚拟机四:类加载机制

虚拟机把描述Class文件加载到内存,并对数据进行校检、转换解析、初始化,最终形成可以被虚拟机使用的Java类型,将这个过程称之为类的加载机制。

一、类的加载过程

类从被加载到内存开始,会经历加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、和卸载(Unloading)这7个阶段,其中验证、准备和解析3个统称为连接(Linking)。

这里写图片描述

其中加载、验证、准备、初始化和卸载这5个接口的顺序是确定的,但是解析阶段是不一定的,因为java语言的动态绑定。

1。加载(Loading) :

加载阶段虚拟机要完成3件事情:

1。通过一个类的全限定名来获取定义此类的二进制流。

2。将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

3。在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口。

类的加载时机
Java虚拟机规范中并没有强制约束什么时候开始进行加载。但是对于初始化阶段,虚拟机规范严格规定了“有且只有5种情况必须立即对类进行初始化”,而加载、验证、准备肯定是在初始化之前要做的,那其实也间接的约束加载,也可以理解为类的加载时机。

1。遇到new、getstatic、pubstatic或invokestatic这4条字节码指定时,如果类没有进行初始化,需要先初始化。这4个指令对应Java代码的场景分别是:使用new关键字创建对象时、读取或者设置一个类的静态自动(不被final修饰的)、调用一个类的静态方法时。

2。使用java.lang.reflect包中的方法对类进行反射调用时,如果没有初始化先初始化。

3.。当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。

4。当虚拟机启动时,用户指定一个要执行的主类,就是程序的入口,带main方法的类,那么要先初始化这个主类。

5。当使用JDK1.7的java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这和对应的类有没初始化,要先触发初始化。

上边5中叫做主动引用,除了这5种情况其他引用类的情况不会被初始化,也叫做被动引用。

被动引用例子1:

/**
*被动使用类字段演示一:
*通过子类引用父类的静态字段,不会导致子类初始化
**/
public class SuperClass{
   
    static{
        System.out.println("SuperClass init!");
    }

    public static int value=123;
}
/**
*子类
**/
public class SubClass extends SuperClass{
   
    static{
        System.out.println("SubClass init!");
    }
}

/**
*非主动使用类字段演示
**/
public class No
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值