单例类可序列化

时间:2018-01-24 01:56:47

标签: java object serialization singleton effective-java

任何人都可以解释这一段:[复制自Effective Java Joshua Bloch第3版第2章第3项]

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

//  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; 
}

2 个答案:

答案 0 :(得分:1)

使用序列化/反序列化,我们可以创建许多导致单例失败的对象。所以要避免这种情况我们必须这样做 实现readResolve()方法。 在deserializaiton期间,在给出反序列化对象之前,它将检查readResolve()方法。 如果覆盖并给出单例实例,则不会创建新对象。

答案 1 :(得分:0)

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

希望这有帮助。