單例 ,真正的單例

2021-09-10 22:47:38 字數 1536 閱讀 5229

單例模式是24種設計模式中的一種,給人的第一反應是乙個類只有乙個例項,非常好理解。

單例模式的優點是減少記憶體開銷,避免資源的多重占用,提供全域性訪問點,嚴格控制訪問,也有缺點沒有介面擴充套件困難。單例模式應用也非常的廣泛,string,mybatis等框架中都有大量的運用。大家也很熟悉什麼懶漢模式,餓漢模式,雙重檢測模式。但是這樣寫的單例是真的單例嗎?

下面我將使用獲取乙個物件的五種方式(new,反射,序列化,轉殖)去獲取乙個單例的例項,看看這樣寫的單例是真正的單例。

1.懶漢模式

看起來

非常標準的懶漢模式,多執行緒下也是安全的,而且是延遲載入,似乎沒有問題。

使用new產生乙個物件是肯定不行的,那麼序列化,反射和轉殖呢?

序列化:

返回false,顯然序列化後,會產生新的物件,單例遭到了破壞

來看看序列化的原始碼:

大概了解了序列化的這部分**後我們在單例中加入這個方法

現在我們重新測試

加入這個方法後,單例沒有被破話。有興趣的小夥伴可以去研究一下反序列化的**;

反射:

在反射面前,任何類都無所遁形,很明顯這個單例也被破壞了。

而且暫時沒有好的方法解決。

轉殖:

轉殖就相對簡單了,這個單例只有重寫了clone方法就可以了

目前我們的單例在反射面前不能真正的單例,那麼看看最推薦的寫法,列舉單例;

現在使用序列化和反射進行攻擊:

可以明顯的看出,列舉單例這序列化面前依然穩定,而且反射不能獲取列舉物件,從而使得列舉單例保持穩定,也就是真正的單例。可以說列舉單例得到了反射和序列化的保駕護航,所以實現單例推薦使用列舉方式,有興趣的小夥伴可以去看看列舉單例反編譯**,就一目了然了。謝謝大家**!

匕首2的真正單例

我之前寫過有關dagger 2的文章。但是,我仍然不了解每個角落。尤其是 singleton注釋可能會引起誤解,因為使用者zhuiden十分友善地指出 快速檢查後,我只能同意。singleton模式僅適用於特定的 component上下文,並且每次呼叫時都會建立乙個 dagger component...

單例 單例模式

簡單的實現乙個單例 instancetype sharedinstance return instance 真正的單例模式 myclass sharedinstance return instance id allocwithzone nszone zone return nil id copywi...

單例(懶漢式單例 餓漢式單例)

public class singleton private static singleton instance new singleton public static singleton getinstance public class singleton public static synchr...