我读过有关单例实现的更好方法。
有人提到,
- 如果单例类实现了 Serialized 接口(interface),那么我们必须定义 readResolve 方法。
但我不明白一件事。如果 readResolve 方法将替换序列化值,那么我们为什么要进行序列化过程呢?相反,我们不需要实现可序列化接口(interface)知道吗?
例如,我有以下 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 类可序列化?
嗯,这根本不是必需的。现实世界中没有需要序列化单例对象的有用场景。单例在其整个生命周期中通常不会改变状态,也不包含任何我们可以保存/恢复的状态。如果确实如此,那么将其设置为单例就已经是错误的。
Java SE API 包含两个单例实现java.lang.Runtime
和java.awt.Desktop
。它们都没有实现可序列化
。这也没有任何意义。
但是,在这种情况下,我们可能需要在实现单例设计模式时处理序列化。
如果父类(super class)实现了序列化接口(interface)怎么办?
如果我们的 Singleton 类需要继承某个类(即 ParentClass)的所有属性,并且该类是可序列化的。例如,
class ParentClass implements Serializable{
}
public class SerializableSingleton extends ParentClass {
// Singleton Code
}
在这种情况下,我们需要采取所有预防措施,例如使所有字段变为 transient 并提供 readResolve()
方法实现。
还有一种方法可以处理这种情况。重写 writeObject() 方法并从中抛出 NotSerializedException
。其行为与您尚未实现 Serialized
接口(interface)相同。
关于java - 为什么我们要实现 Serialized 接口(interface),然后在同一个类中添加 readResolve,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34529213/