破壞單例模式之靜態方法、靜態代碼塊和構造方法執行順序

昨天看了凱子哥的單例設計模式,裏面講到了破壞單例模式的方法,具體內容請看原文,這裏來分析一下原理。爲什麼通過靜態代碼塊就會破壞單例模式呢,這就是今天要講的故事:靜態代碼塊在什麼時候執行?
上代碼

class Parent {
    {
        System.out.println("i am parent block");
    }
    static {
        System.out.println("i am parent static block");
    }
    public Parent() {
        System.out.println("i am parent constructor");
    }
}
class Child extends Parent {
    {
        System.out.println("i am child block");
    }
    static {
        System.out.println("i am child static block");
    }
    public Child() {
        System.out.println("i am child constructor");
    }
}

這個時候new Child(),會發生什麼?

i am parent static block
i am child static block
i am parent block
i am parent constructor
i am child block
i am child constructor

從上面的打印結果來看,static block的優先級最高,先執行父類的static block->執行子類的static block->父類普通block->父類的constructor->子類普通block->子類constructor


這就是爲什麼當在靜態代碼塊裏面去new對象的時候,會破壞單例模式,因爲靜態代碼塊是主動執行的,當加載到的這個class文件內有靜態代碼塊,那麼靜態代碼塊會先去執行,靜態代碼塊裏面初始化了一次,手動調用的時候又初始化了一次。
如果是靜態內部類實現的單例模式,這種破壞方法不起作用,靜態內部類只會執行一次,當SingletonDestyoyer中的靜態代碼塊去調用SingletonStatic.getInstance()的時候,靜態內部類還沒有初始化完成,返回null,不會出現多次初始化的情況。
Ps:這塊還是有點迷糊,如果有明白人,歡迎交流!!!

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