昨天看了凱子哥的單例設計模式,裏面講到了破壞單例模式的方法,具體內容請看原文,這裏來分析一下原理。爲什麼通過靜態代碼塊就會破壞單例模式呢,這就是今天要講的故事:靜態代碼塊在什麼時候執行?
上代碼
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:這塊還是有點迷糊,如果有明白人,歡迎交流!!!