反射對單例模式的破壞

反射對單例模式的破壞

首先咱們依舊是使用餓漢式做爲測試。咱們把以前寫的餓漢式的代碼貼上來。java

public class HungrySingleton {

    private final static HungrySingleton hungrySingleton;

    static{
        hungrySingleton = new HungrySingleton();
    }
    private HungrySingleton(){
    }
    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}
複製代碼

而後咱們在測試類中使用反射來對這個單例進行攻擊。測試

public class SingletonTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException {
        HungrySingleton instance = HungrySingleton.getInstance();
        Class<HungrySingleton> hungrySingletonClass = HungrySingleton.class;
        Constructor<HungrySingleton> constructor = hungrySingletonClass.getConstructor();
        constructor.setAccessible(true);
        HungrySingleton newInstance = constructor.newInstance();
        System.out.println(instance == newInstance);
    }

複製代碼

這個輸出結果可想而知false。那麼咱們怎麼樣防治這種反射攻擊呢?下面咱們給出一種解決方案spa

private final static HungrySingleton hungrySingleton;

    static{
        hungrySingleton = new HungrySingleton();
    }
    private HungrySingleton(){
        if(hungrySingleton != null){
            throw new RuntimeException("單例構造器禁止反射調用");
        }
    }
    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
複製代碼

咱們再使用這個測試類進行測試就發現報出異常。那這是餓漢式的單例若是是懶漢式的單例呢?可否經過這種方式來實現?答案是不能。至於緣由的你們想一想就知道了。懶漢式一開始加載的時候成員變量是null,也就沒法經過判斷是否爲null來阻止反射獲取實例。code

相關文章
相關標籤/搜索