摘要:枚舉單例以上是一個單例枚舉的例子,而我們要獲取該實例只需要,并且此種方式可以保證該單例線程安全防反射攻擊防止序列化生成新的實例。
關(guān)于單例模式,相信大家都所有了解,比較經(jīng)典的實現(xiàn)有餓漢式、借助內(nèi)部類、雙重鎖檢測,這些實現(xiàn)可以保證線程安全,但是在某些特殊情況下并不能夠保證僅僅只有一個單例,因為像序列化、反射攻擊等往往可以生成新的實例對象,本文將重點分析枚舉單例模式如何防止反射攻擊。
枚舉單例:
public enum Singleton { INSTANCE { @Override protected void read() { System.out.println("read"); } @Override protected void write() { System.out.println("write"); } }; protected abstract void read(); protected abstract void write(); }
以上是一個單例枚舉的例子,而我們要獲取該實例只需要Singleton.INSTANCE,并且此種方式可以保證該單例線程安全、防反射攻擊、防止序列化生成新的實例。
枚舉單例關(guān)于防反射攻擊,當然和枚舉的實現(xiàn)有關(guān),枚舉也是java類,我們對Singleton的class進行反編譯,可以得到一個新的類(對于枚舉的實現(xiàn)不了解的可以補補相關(guān)知識):
反編譯后的類:
public abstract class Singleton extends Enum { private Singleton(String s, int i) { super(s, i); } protected abstract void read(); protected abstract void write(); public static Singleton[] values() { Singleton asingleton[]; int i; Singleton asingleton1[]; System.arraycopy(asingleton = ENUM$VALUES, 0, asingleton1 = new Singleton[i = asingleton.length], 0, i); return asingleton1; } public static Singleton valueOf(String s) { return (Singleton)Enum.valueOf(singleton/Singleton, s); } Singleton(String s, int i, Singleton singleton) { this(s, i); } public static final Singleton INSTANCE; private static final Singleton ENUM$VALUES[]; static { INSTANCE = new Singleton("INSTANCE", 0) { protected void read() { System.out.println("read"); } protected void write() { System.out.println("write"); } }; ENUM$VALUES = (new Singleton[] { INSTANCE }); } }
看到了這個類的真身過后,相信很多人對于枚舉單例防反射的的原理就了解了:
類的修飾abstract,所以沒法實例化,反射也無能為力。
關(guān)于線程安全的保證,其實是通過類加載機制來保證的,我們看看INSTANCE的實例化時機,是在static塊中,JVM加載類的過程顯然是線程安全的。
對于防止反序列化生成新實例的問題還不是很明白,一般的方法我們會在該類中添加上如下方法,不過枚舉中也沒有顯示的寫明該方法。
//readResolve to prevent another instance of Singleton private Object readResolve(){ return INSTANCE; }
如果寫的有問題,歡迎指正~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64156.html
摘要:防止指令重排序防止時指令重排序?qū)е缕渌€程獲取到未初始化完的對象。枚舉類默認枚舉實例的創(chuàng)建是線程安全的,所以不需要擔心線程安全的問題。 單例模式是23種GOF模式中最簡單,也是最經(jīng)常出現(xiàn)的一種設計模式,也是面試官最常愛考的一種模式,為什么呢?因為單例模式足夠簡單,編寫一個單例模式代碼幾分鐘就能搞定,所以設計模式中面試官通常會選取單例模式作為出題。下面把單例模式分幾個點,分別說說哪些地方...
摘要:然而我只需要將這個單例類的構(gòu)造函數(shù)通過反射設置成可以訪問,然后就能通過反射調(diào)用該構(gòu)造函數(shù),進而生成新的對象實例。針對這種攻擊,一種可行的防御措施是在單例類的構(gòu)造函數(shù)內(nèi)定義一個布爾變量,初始化為。當構(gòu)造函數(shù)執(zhí)行后,該變量被置為。 ABAP CLASS zcl_jerry_singleton DEFINITION PUBLIC FINAL CREATE PRIVATE . PUB...
閱讀 2570·2021-09-06 15:02
閱讀 3200·2021-09-02 10:18
閱讀 2821·2019-08-30 15:44
閱讀 685·2019-08-30 15:43
閱讀 1948·2019-08-30 14:08
閱讀 2758·2019-08-30 13:16
閱讀 1397·2019-08-26 13:52
閱讀 931·2019-08-26 12:21