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。现在您有两个单例对象,它们是生活在同一个应用程序中的不同对象。
希望这有帮助。