立即初始化的六中情况(加载、 验证、 准备自然需要在此之前开始)

1) 遇到new、 getstatic、 putstatic或invokestatic这四条字节码指令时, 如果类型没有进行过初始
化, 则需要先触发其初始化阶段。 能够生成这四条指令的典型Java代码场景有:
·使用new关键字实例化对象的时候。
·读取或设置一个类型的静态字段(被final修饰、 已在编译期把结果放入常量池的静态字段除外)
的时候。
·调用一个类型的静态方法的时候。
2) 使用java.lang.reflect包的方法对类型进行反射调用的时候, 如果类型没有进行过初始化, 则需
要先触发其初始化。

3) 当初始化类的时候, 如果发现其父类还没有进行过初始化, 则需要先触发其父类的初始化。
4) 当虚拟机启动时, 用户需要指定一个要执行的主类( 包含main()方法的那个类) , 虚拟机会先
初始化这个主类。
5) 当使用JDK 7新加入的动态语言支持时, 如果一个java.lang.invoke.MethodHandle实例最后的解
析结果为REF_getStatic、 REF_putStatic、 REF_invokeStatic、 REF_newInvokeSpecial四种类型的方法句
柄, 并且这个方法句柄对应的类没有进行过初始化, 则需要先触发其初始化。
6) 当一个接口中定义了JDK 8新加入的默认方法( 被default关键字修饰的接口方法) 时, 如果有
这个接口的实现类发生了初始化, 那该接口要在其之前被初始化。

接口的加载过程与类加载过程稍有不同, 针对接口需要做一些特殊说明: 接口也有初始化过程,
这点与类是一致的, 上面的代码都是用静态语句块“static{}”来输出初始化信息的, 而接口中不能使用“static{}”语句块, 但编译器仍然会为接口生成“<clinit>()”类构造器[2], 用于初始化接口中所定义的成员变量。 接口与类真正有所区别的是前面讲述的六种“有且仅有”需要触发初始化场景中的第三种:当一个类在初始化时, 要求其父类全部都已经初始化过了, 但是一个接口在初始化时, 并不要求其父接口全部都完成了初始化, 只有在真正使用到父接口的时候(如引用接口中定义的常量) 才会初始化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值