Java 寫入 readResolve方法解決 單例類序列化後破壞唯一實例規則的問題

Java 寫入 readResolve方法解決 單例類序列化後破壞唯一實例規則的問題

  • 單例類序列化後, 在反序列化會克隆出新的對象破壞了單例規則. 所以需要序列化的單例類需要含有 readResolve方法. 反序列化時會自動調用此方法返回對象, 來保證對象唯一性

public class EagerSingleton implements Serializable {
    private static final long serialVersionUID = 7073777279565036708L;

    private static volatile EagerSingleton instance = new EagerSingleton();

    /**
     * 爲了防止通過反射機制實例化構造方法拋異常
     * */
    private EagerSingleton() {
        if (instance != null) {
            throw new RuntimeException("不允許被反射實例化");
        }
    }

    public static EagerSingleton getInstance() {
        return instance;
    }

    /**
     * readResolve方法的作用爲防止序列化單例時破壞唯一實例的規則
     * */
    private Object readResolve() throws ObjectStreamException {
        return instance;
    }

}

public class App {
    public static void main(String[] args) {
        EagerSingleton o = EagerSingleton.getInstance();
        System.out.println("通過單例類實例化對象 " + EagerSingleton.getInstance());

        try {
            File file = new File("D:" + File.separator + "EagerSingleton");
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
            /** 對象寫入到文件*/
            oos.writeObject(o);

            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
            /** 從磁盤讀取對象*/
            System.out.println("從磁盤讀取的對象 " + ois.readObject());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

  • 輸出 (單例類不包含 readResolve方法時

通過單例類實例化對象 com.test.web4.singleton.EagerSingleton@eed1f14
從磁盤讀取的對象 com.test.web4.singleton.EagerSingleton@7a07c5b4

  • 輸出 (單例類包含 readResolve方法時

通過單例類實例化對象 com.test.web4.singleton.EagerSingleton@eed1f14
從磁盤讀取的對象 com.test.web4.singleton.EagerSingleton@eed1f14

  • 可以看出對象地址包含 readResolve方法和不包含是有區別的

如果您覺得有幫助,歡迎點贊哦 ~ 謝謝!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章