类初始化时机

虚拟机规范中严格规定有且只有5种情况下,当类没有初始化时必须立即对类进行初始化:

    1. 遇到new、getstatic、putstatic或invokeStatic这4条字节码指令时。常见场景:
    • 使用new关键字实例化对象时,触发new;
    • 读取类变量时,触发getstatic;(final常量除外)
    • 设置类变量时,触发putstatic;
    • 调用类的静态方法时,触发invokeStatic;
    1. 虚拟机启动时,需指定一个要执行的主类(含有main()的类),虚拟机会先初始化该类;
    1. 初始化一个类时,当其父类没有初始化,则需要先触发其父类的初始化;
    1. 使用java.lang.reflect包中的方法对类进行反射调用时;
    1. 当java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且该句柄所对应的类没有进行过初始化;
      你所不知道的MethodHandle

上面讲到final常量不能触发类初始化,是由于在编译时已把数据放入常量池的静态字段,当读取类的static final字段时,并不需要初始化类,而是从常量池中去获取相应的数据

上述的5种场景的行为都是对类的一个主动引用过程。除此之外,还有被动引用并不会除非类的初始化过程。

猜你喜欢

转载自blog.csdn.net/weixin_33692284/article/details/87421145