簡體   English   中英

為什么我們要實現Serializable接口,然后在同一類中添加readResolve

[英]Why should we implement Serializable interface and then add readResolve in same class

我已經閱讀了有關實現Singleton的更好方法。

有人提到,

  • 如果單例類正在實現Serializable接口,那么我們必須定義readResolve方法。

但是我不明白一件事。 如果readResolve方法將替換序列化的值,那么為什么我們要進行序列化過程呢? 相反,我們不需要實現可序列化的接口知道嗎?

例如,我有以下Singleton類,

package singleton;

import java.io.Serializable;

public class ClassicSingleton implements Serializable {

private static final long serialVersionUID = 1L;

private static ClassicSingleton classicSingleton = new ClassicSingleton();

private int num;

private ClassicSingleton() {

}

public int getNum() {
    return num;
}

public void setNum(int num) {
    this.num = num;
}

public static ClassicSingleton getInstance() {
    return classicSingleton;
}

protected Object readResolve() {
    ClassicSingleton cs = getInstance();
    cs.setNum(23);
    return cs;
}

}

這就是我要進行序列化的地方

package singleton;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SingletonExample {
public static <T> void main(String args[]) throws FileNotFoundException,
        IOException, ClassNotFoundException {

    ClassicSingleton classicSingleton = ClassicSingleton.getInstance();
    classicSingleton.setNum(5);
    serialize(classicSingleton);
    }

public static <T> void serialize(T t) throws FileNotFoundException,
        IOException {

    ObjectOutputStream oop = new ObjectOutputStream(new FileOutputStream(
            "file1.txt"));
    oop.writeObject(t);
    oop.close();

}

}

反序列化代碼

package singleton;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class SerializeInAnotherFIle {

public static <T> void main(String[] args) throws FileNotFoundException,
        ClassNotFoundException, IOException {

    T object = deSerialize();

    ClassicSingleton classicSingleton= (ClassicSingleton) object;
    ClassicSingleton classicSingleton2 = deSerialize();
    System.out.println("Is serialized and deserialized are same? :"+(classicSingleton == classicSingleton2));

    System.out.println("Classic Singleton :"
            + classicSingleton.getNum());

}

public static <T> T deSerialize() throws FileNotFoundException,
        IOException, ClassNotFoundException {

    ObjectInputStream oip = new ObjectInputStream(new FileInputStream(
            "file1.txt"));
    T object = (T) oip.readObject();
    oip.close();
    return object;

}}

由於我定義了readResolve方法,因此我的輸出始終為23。序列化的值不再出現。 所以我的疑問是為什么將Serialization和readResolve放在一起,因為兩者的作用相反。

我在http://codepumpkin.com/serializable-singleton-design-pattern/找到了這個問題的答案

這是此鏈接的摘要:

為什么我們需要使Singleton類可序列化?

好吧,這根本不是必需的。 在現實世界中,沒有有用的場景要求我們序列化Singleton對象。 單例通常在其整個生命周期內都不會改變狀態,也不包含我們可以保存/恢復的任何狀態。 如果是這樣,那么將其設為單身已經是錯誤的。

Java SE API包含兩個Singleton實現java.lang.Runtimejava.awt.Desktop 他們都沒有實現可serializable 這也沒有任何意義。

但是,在一種情況下,我們可能需要在實現Singleton Design Pattern時處理序列化。

如果超類實現了序列化接口怎么辦?

如果需要我們的Singleton類繼承某個類(即ParentClass)的所有屬性,並且該類是Serializable。 例如,

class ParentClass implements Serializable{

}
public class SerializableSingleton extends ParentClass {
     // Singleton Code
}

在這種情況下,我們需要采取所有預防措施,例如使所有字段變為瞬態並提供readResolve()方法實現。

還有另一種方法來處理這種情況。 重寫writeObject()方法並NotSerializableException拋出NotSerializableException 與未實現Serializable接口的行為相同。

原因是沒有人可以通過序列化和反序列化單例來創建單例對象的另一個實例。

readResolve用於替換從流讀取的對象。 您使用cs.setNum(23)對其進行了硬編碼; 這就是為什么它總是返回23的原因。如果您不想對數據進行操作,請按如下所示編輯代碼

protected Object readResolve() {
  return this;
}

原因:readObject返回后將調用readResolve。 方法返回的對象將替換返回給ObjectInputStream.readObject用戶的該對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM