关于java:Singleton类可序列化

Singleton classes serializable

本问题已经有最佳答案,请猛点这里访问。

有人能解释这段话吗?[复制自有效Java Joshua Bloch第三版第2章第3项]

要使使用这两种方法之一(即保持构造函数私有并导出公共静态成员以提供对唯一实例的访问)的singleton类可序列化,仅向其声明中添加可序列化的实现是不够的。要维护singleton保证,请将所有实例字段声明为transient并提供readresolve方法。否则,每次反序列化一个序列化实例时,都会创建一个新实例,在我们的示例中,这会导致假ELVIS目击。要防止这种情况发生,请将此readresolve方法添加到ELVIS类:

1
2
3
4
5
6
//  readResolve method  to  preserve    singleton   property
private Object  readResolve()  
{
//  Return  the one true    Elvis   and let the garbage collector //    take    care    of  the Elvis   impersonator.
return  INSTANCE;
}


使用序列化/反序列化,我们可以创建许多导致单例失败的对象。为了避免这种情况,我们必须实现readresolve()方法。在反序列化期间,在给出反序列化对象之前,它将检查readresolve()方法。如果您重写并提供单例实例,那么将不会创建新对象。


想象一下这个场景,您的应用程序运行并序列化单例(从现在起称为s1)。整个周末,应用程序被拆除并重新启动。当进程启动时会创建一个新的单例(现在是s2)。当应用程序使用s2运行时,另一个对象反序列化s1。现在您有两个单例对象,它们是生活在同一个应用程序中的不同对象。

希望这有帮助。