美文网首页我爱编程
JVM加载类的时机

JVM加载类的时机

作者: 四喜汤圆 | 来源:发表于2018-07-26 12:59 被阅读16次
    image.png

    类的生命周期

    加载,连接(验证,准备,解析),初始化,使用,卸载

    image.png
    摘自 深入理解java虚拟机【Java虚拟机类生命周期】

    对类的主动引用(5种),会触发类的初始化

    Java虚拟机规范中对于类加载的时机没有明确的规范,但是明确规定了有且只有5种情况下,必须立即对类进行初始化。(既然执行了初始化,加载、连接操作肯定在初始化之前已经开始(并不保证结束的顺序)

    • 读取或设置类的静态变量、访问类的静态方法时,若该类还未被初始化,则需先进行初始化
    • 创建类的实例时,若该类还未被初始化,则需先进行初始化
      1. 通过new关键字创建
      2. 通过反射方法(java.lang.reflect)创建
    • 当要初始化一个类时,若其父类还未初始化,则先初始化其父类
    • JVM启动时,会先初始化包含main()方法的类
    • 当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个句柄所对应的类没有进行过初始化,则需先触发其初始化。

    上述5种情况称为对类的主动引用,下面介绍几种对类的被动引用情况

    对类的被动引用(列举3个),不会触发类的初始化

    • 通过子类引用父类的静态变量,不会触发子类的初始化
    // 父类
    public class SuperClass{
        public static int a=1;
    }
    
    // 子类
    public class SubClass extends SuperClass{
        public static void main(String[] args){
            System.out.println(SubClass.a)
        }
    }
    
    • 通过数组定义引用类,不会触发该类的初始化
    public class Main{
        public static void main(String[] args){
            SuperClass[] arr=new SuperClass[10];
        }
    }
    
    • 通过类名访问该类中的常量,不会触发该类的初始化
    public class ConstClass{
        public static final String HELLO_WORLD="hello";
    }
    
    public class Main{
        public static void main(String[] args){
            ConstClass.HELLO_WORLD;
        }
    }
    

    参考文献

    JVM_周志明

    相关文章

      网友评论

        本文标题:JVM加载类的时机

        本文链接:https://www.haomeiwen.com/subject/cnqvmftx.html