單例模式,解決單例破壞。

2021-10-19 19:19:24 字數 1539 閱讀 1936

破壞單例模式的三種方法(執行緒安全情況下)

單例模式有 3 個特點:

單例類只有乙個例項物件;

該單例物件必須由單例類自行建立;

單例類對外提供乙個訪問該單例的全域性訪問點。

單例模式的優點和缺點:

單例模式的優點:

單例模式可以保證記憶體裡只有乙個例項,減少了記憶體的開銷。

可以避免對資源的多重占用。

單例模式設定全域性訪問點,可以優化和共享資源的訪問。

單例模式的缺點:

單例模式一般沒有介面,擴充套件困難。如果要擴充套件,則除了修改原來的**,沒有第二種途徑,違背開閉原則。

在併發測試中,單例模式不利於**除錯。在除錯過程中,如果單例中的**沒有執行完,也不能模擬生成乙個新的物件。

單例模式的功能**通常寫在乙個類中,如果功能設計不合理,則很容易違背單一職責原則。

public

class

lazysingleton

public

static lazysingleton getinstance()

}}return instance;

}}

/**

* 執行緒安全

* 不足之處

* 1、不管是否使用該物件都會建立物件占用記憶體資源

* 2、建立的物件不可變

*/public

class

hungrysingleton

public

static hungrysingleton getinstance()

}

public object clone()

throws clonenotsupportedexception

利用反射可以訪問單例物件的私有構造方法,生成新的物件破壞單例模式。

解決方法:

設定乙個標誌,修改私有建構函式。

private

static

boolean isfirst =

true;if

(isfirst)}}

else

仍然有缺陷,反射可以修改isfirst的值。

懶漢式中如果反射先構造則全域性訪問點將無法訪問.

將單例物件序列化再反序列化時,反序列化的物件與單例物件不是同乙個物件。

解決方法:

加入readresolve()這個方法.

private object readresolve()

使用列舉的方法可以規避反射,序列化,轉殖破壞單例模式

列舉的私有構造方法不能被反射使用,反射無法找到該方法。

列舉不能實現clone方法,所以列舉不能被轉殖

列舉沒有序列化id,但是被反序列化時,與原來的單例物件是同乙個物件。

public

enum singleton

單例設計模式 序列化破壞單例模式?

1 問題猜想,假如將乙個物件通過序列化放到乙個檔案後,再取出來看是否與本身相等?public class hungrysingleton implements serializable private hungrysingleton public static hungrysingleton get...

readResolve 解決反射破壞單例

具體的操作和測試在單例的部落格中都有提到 單例模式的幾種寫法 單例的寫法和測試結果此片文章不再演示,直接去找readresolve 是怎樣防止破壞單例的。在測試 中用到了 objectinputstream 進入到這個 中,找到 片段 走到readobject 方法中。在readobject 方法中...

附 單例模式的破壞

序列化物件對單例模式的破壞與恢復 首先這是乙個餓漢式的單例物件構建方式,一般情況下獲取到的都是同乙個單例物件 但是當序列化寫入本地再讀入記憶體時,會重新建立乙個單例物件 為什麼會在讀入序列化後的物件時會讓單例模式失效呢?這兒從readobject 方法入手 進入這個方法後 private 進入pri...