jvm-008(张龙老师jvm教程) 初始化加载顺序代码示例分析

    技术2022-07-10  144

    jvm-008

    一、初始化的执行顺序:类的初始化顺序是按照代码逻辑自上而下依次执行的。

    代码1:

    public class TestCode06 { public static void main(String[] args) { MyParent06 instance = MyParent06.getInstance(); System.out.println("a : " + instance.a);//1 System.out.println("b : " + instance.b);//0 } } class MyParent06 { public static int a; public static int b = 0; public static MyParent06 mp = new MyParent06(); public MyParent06() { a ++ ; b ++ ; } public static MyParent06 getInstance() { return mp; } }

    运行结果:

    a : 1 b : 1

    分析:首先进行类的加载、连接、初始化,在连接的准备阶段,对类的静态变量赋予零值,准备阶段过后,a = 0, b = 0, mp = null。在main方法中,MyParent06 instance = MyParent06.getInstance()代码执行的时候,会执行 MyParent06 类中 mp = new MyParent06(),会引发 MyParent06 类的初始化。初始化顺序分别是 a 不赋值, b = 0,mp = new MyParent06()会执行,在执行这一步的时候,会调用 MyParent06 类的实例代码块 {

            a ++ ;

            b ++ ;

    }, 执行过后,a 和 b的值分别为 a = 1, b = 1,所以在main方法中, 在获取 instance.a / instance.b的数值的时候,结果都是1。

     

    ============================分割符==============================

     

    代码2:

    public class TestCode06 { public static void main(String[] args) { MyParent06 instance = MyParent06.getInstance(); System.out.println("a : " + instance.a);//1 System.out.println("b : " + instance.b);//0 } } class MyParent06 { public static int a; public static MyParent06 mp = new MyParent06(); public static int b = 0; public MyParent06() { a ++ ; b ++ ; } public static MyParent06 getInstance() { return mp; } }

    运行结果:

    a : 1 b : 0

    分析:代码2与代码1的唯一区别就是

    public static MyParent06 mp = new MyParent06() 和 public static int b = 0的顺序发生了变化,但是结果就不一样了。

    同代码的原理:MyParent06 类首先被加载,加载过后的 a = 0, b = 0, mp = null;之后再main方法中执行 MyParent06 instance = MyParent06.getInstance() 会触发 MyParent06 类的初始化,初始化顺序与代码1有所不同:

    首先 a 不赋值,仍旧是0,然后 是 mp = new MyParent06();此时创建对象会调用 MyParent06 类的实例代码块 {

           a ++ ;

            b ++ ;

    },执行过后, a = 1, b = 1。再后面执行 int b = 0 的赋值过程,b又变为0。所以在main方法中,打印结果 instance.a = 1, instance.b = 0;

    Processed: 0.012, SQL: 9