我们一直在了解如何使用'readResolve()'来确保在序列化Singleton时具有单一性。但是为什么要首先想要序列化Singleton的实际用例是什么?
编辑:请注意:问题是关于为什么要序列化Singleton,而不是安全地执行此操作的方法。
编辑:请注意:问题是关于为什么要序列化Singleton,而不是安全地执行此操作的方法。
readResolve()
。Hot Spot:
Multithreading - A special care should be taken when singleton has to be used in a multithreading application.
Serialization - When Singletons are implementing Serializable interface they have to implement readResolve method in order to avoid having 2 different objects.
Classloaders - If the Singleton class is loaded by 2 different class loaders we'll have 2 different classes, one for each class loader.
Global Access Point represented by the class name - The singleton instance is obtained using the class name. At the first view this is an easy way to access it, but it is not very flexible. If we need to replace the Sigleton class, all the references in the code should be changed accordinglly.
该对象可能是单例的,但它可能是较大结构的一部分,而该结构并不完全知道它。例如,它可以实现一个接口,该接口可以有几个不同的实现(因此具有多个实例):
interface StringSink extends Serializable { void dump(String s); }
class MultiDumper implements Serializable {
private final StringSink sink;
public MultiDumper(StringSink sink){ this.sink = sink; }
void doSomeStuff(Collection<String> strings){
for (String s : strings) sink.dump(s);
}
}
StringSink
。由于只有一个标准输出,因此我们可以将其设置为单例模式:/** Beware: Not good for serializing! */
class StdoutStringSink {
public static final StdoutStringSink INSTANCE = new StdoutStringSink();
private StdoutStringSink(){}
@Override
public void dump(String s){ System.out.println(s); }
}
我们可以这样使用它:
MultiDumper dumper = new MultiDumper(StdoutStringSink.INSTANCE);
StdoutStringSink
实例。