Java类初始化顺序演示

class SingleTon {
    private static SingleTon singleTon = new SingleTon();//A
    public static int count1;//B
    public static int count2 = 0;//C
    static {
        System.out.println("static code");
    }

    private SingleTon() {
        System.out.println("SingleTon init");
        System.out.println("singleTon==null"+(singleTon==null));
        count1++;
        count2++;
        System.out.println("SingleTon init count1="+count1);
        System.out.println("SingleTon init count2="+count2);
    }

    public static SingleTon getInstance() {
        System.out.println("getInstance singleTon==null"+(singleTon==null));
        return singleTon;
    }
}
public class Test {
    static {
        System.out.println("TEST init");
    }

    public static void main(String[] args) {

        SingleTon singleTon = SingleTon.getInstance();
        System.out.println(singleTon.count1);
        System.out.println(singleTon.count2);
    }
}

写出上面程序的输出结果
大家可以大胆假设
然后放到ide中执行一下看看是否跟你想的一样。

TEST init (1)
SingleTon init (2)
singleTon==null true (3)
SingleTon init count1=1 (4)
SingleTon init count2=1 (5)
static code (6)
getInstance singleTon==nullfalse (7)
1 (8)
0 (9)

从第几条开始跟你想的不一样了呢。
解释一下
1.这个跟类的初始化有关,在调用类的静态方法,静态变量的时候(final修饰的静态常量除外)会触发类的初始化。SingleTon.getInstance();是调用了静态方法,会触发类的初始化。

2.静态代码块是在类初始化后执行的,main方法所在的类内的静态代码块又是最先执行的
3.在类初始化之前有一个准备阶段,按照成员变量的顺序,进行顺序赋予默认值。对象类型的变量会先付成null,然后在初始化的时候才在堆上new一个对象的内存空间。静态变量也是这样,先初始化成0,然后在初始化阶段对给定的值付给变量。
4.也就是初始化之前的准备阶段,singleTon =null ,count1=0,count2=0,然后执行类初始化。这个时候先执行singleTon=new SingleTon();这个时候会执行构造方法,在执行过程中,虽然为singleTon开辟了内存空间,但是还有赋值给singleTon,所以这个时候singleTon==null;然后执行count1++,count2++
这个时候,count1,count2都是1。此时singleTon赋值结束。
5.然后顺序执行,count1不需要处理,count2需要赋值成0.
6.目前为止,类初始化执行完成。这个时候singleTon.count1 肯定是1,singleTon.count2 的结果是0.

思考一下?把C行的代码和A行的代码换下位置,会发生什么,输出结果有什么变化。

你可能感兴趣的:(Java类初始化顺序演示)