類加載帶來的數據不一致的”坑“

首先觀察下面代碼,並想下輸出結果是什麼

public class SinglePattern{

    private static SinglePattern instance = new SinglePattern();//在類的裝載就直接實例化
    public static int a;
    public static int b = 2;

    private SinglePattern(){
        a++;
        b++;
    }
    public static SinglePattern getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        SinglePattern ins = SinglePattern.getInstance();
        System.out.println("a:="+ins.a);
        System.out.println("b:="+ins.b);
    }
}

上面就是一個單例模式唄

然後我不做任何修改,改變類實例化的一行代碼的位置,想想輸出結果是什麼?

public class SinglePattern{

    public static int a;
    public static int b = 2;

    private static SinglePattern instance = new SinglePattern();//在類的裝載就直接實例化

    private SinglePattern(){
        a++;
        b++;
    }
    public static SinglePattern getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        SinglePattern ins = SinglePattern.getInstance();
        System.out.println("a:="+ins.a);
        System.out.println("b:="+ins.b);
    }
}

想到結果了沒??

第一個運行結果爲:
這裏寫圖片描述

第二個運行結果爲:
這裏寫圖片描述

WTF?

就改變一行代碼的位置,沒有其它大的改動,就結果不一樣了!!

其實這是類加載過程產生的問題,對類加載過程詳細瞭解。可以參考:https://blog.csdn.net/weijifeng_/article/details/79894742

對於兩個代碼分析詳解

1 .準備階段

instance = null;
a = 0;
b = 0;

2 .初始化階段

new SinglePattern() ; a = 1; b = 1;
public static int a;  a沒有指定值,就是上一步的1
public static int b = 2; b有指定初始值,初始化階段時,b = 2;

所以這就是第一種執行結果爲a = 1, b = 2的原因了

1 .準備階段

instance = null;
a = 0;
b = 0;

2 .初始化階段

public static int a;  a沒有指定值,就是上一步的0
public static int b = 2; b有指定初始值,初始化階段時,b = 2;  
new SinglePattern() ; a = 1; b = 3;

這就是產生結果不一樣的原因了!
類加載的準備階段和初始化階段都嚴格執行自己的工作,並且在初始化階段,嚴格按照指令從上到下的順序就行內存值分配

所以在瞭解裝載的過程,就應該清楚自己取什麼階段的值,保證取值不會發生錯誤

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章