JAVA虚拟机的类加载过程(1)

    大家好,今天和大家分享JAVA中类加载过程的部分知识。

    一开始我们先来了解一下JAVA的类加载过程的定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的JAVA类型,这就是虚拟机的类加载机制。

    类从被加载到虚拟机内存中开始,到卸载出内存为止,整个过程包括了加载,连接,初始化,使用和卸载五个阶段,然后在连接过程中,又包括了验证,准备,解析三个小阶段,如下图所示:

    在类的加载过程中,加载,验证,准备,初始化,卸载这5个阶段的开始顺序是固定的,必须前一个开始后,由于某些操作,触发后一个过程,但是仅限于开始顺序一致,至于完成顺序则是不一定的,因为这些阶段在运行过程中往往是相互交叉的混合进行,通常是在一个阶段中调用或者激活下一个阶段。

    而在这些过程中,解析阶段的发生时机是不确定的,解析阶段由于要支持运行时绑定,所以可能会在初始化阶段开始后开始。

    在《JAVA虚拟机规范》中,并没有对什么时候开始类加载阶段做强制要求,而是交由不同的虚拟机进行灵活实现,但是对于初始化阶段,虚拟机规范中做出了明确而且十分严格的规定,只有以下5中情况才会触发初始化阶段:

    1.遇到new,getstatic,putstatic,invokestatic这4条字节码指令时,如果类还没有进行初始化,那么将触发类的初始化阶段。

    2.使用java.lang.reflect包的方法进行反射调用时,如果类没有初始化,那么将触发类的初始化。

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

    4.当虚拟机启动时,虚拟机将初始化用户所指定的主类。

    5.如果使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandler实例最后的解析结果是REF_getStatic,REF_putStatic,REF_invokeStatic的方法句柄时,如果句柄对应的类没有进行初始化,则将触发类的初始化。

    以上5种场景被称作是对类的主动引用,其余情况都不会触发类的初始化,被称作被动引用。

    下面我们来看一些被动引用的例子。

    1.对于静态字段,只有直接定义这个字段的类才会被初始化,所以如果通过子类来引用父类的静态字段,则不会触发子类初始化,所以下面的代码输出只有“superClass init”。

    2.通过数组定义来引用类,不会触发类的初始化,所以下面代码不会输出“superClass init”。

    3.常量在编译阶段会存入调用类的常量池中,本质上并没有引用到定义常量的类,所以不会触发类的初始化,所以以下代码,不会输出“ConstClass init”。

    以上就是被动引用的部分示例,今天的分享就到这里,后续对于JAVA虚拟机的类加载过程,我们会有更加详尽的分享。如果大家觉得我们的文章对您有用,请关注我们的公众号,每天一篇实用文哦。

    


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值