单例 类 可序列化
Singleton classes serializable
任何人都可以解释这一段:[从 Effective Java Joshua Bloch 第 3 版第 2 章第 3 项复制]
要使使用这些方法之一的单例 class(即保持构造函数私有并导出 public 静态成员以提供对唯一实例的访问)可序列化,这还不够只是将 implements Serializable 添加到它的声明中。为维护单例保证,声明所有实例字段为瞬态并提供 readResolve 方法。否则,每次反序列化序列化实例时,都会创建一个新实例,就我们的示例而言,这会导致虚假的猫王目击事件。为防止这种情况发生,请将此 readResolve 方法添加到 Elvis class:
// 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;
}
想象一下这种情况,您的应用程序运行并序列化 Singleton(从现在起称为 s1)。在周末,应用程序被关闭并重新启动。进程启动时会创建一个新的单例(现在是 s2)。当应用程序 运行 使用 s2 时,另一个对象反序列化 s1。你现在有两个单例,它们是生活在同一个应用程序中的不同对象。
希望对您有所帮助。
使用serialization/deserializaiton我们可以创建许多导致单例失败的对象。所以为了避免这种情况,我们必须
实现 readResolve() 方法。
在反序列化期间,在提供反序列化对象之前,它将检查 readResolve() 方法。
如果您覆盖并提供单例实例,则不会创建新对象。
任何人都可以解释这一段:[从 Effective Java Joshua Bloch 第 3 版第 2 章第 3 项复制]
要使使用这些方法之一的单例 class(即保持构造函数私有并导出 public 静态成员以提供对唯一实例的访问)可序列化,这还不够只是将 implements Serializable 添加到它的声明中。为维护单例保证,声明所有实例字段为瞬态并提供 readResolve 方法。否则,每次反序列化序列化实例时,都会创建一个新实例,就我们的示例而言,这会导致虚假的猫王目击事件。为防止这种情况发生,请将此 readResolve 方法添加到 Elvis class:
// 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;
}
想象一下这种情况,您的应用程序运行并序列化 Singleton(从现在起称为 s1)。在周末,应用程序被关闭并重新启动。进程启动时会创建一个新的单例(现在是 s2)。当应用程序 运行 使用 s2 时,另一个对象反序列化 s1。你现在有两个单例,它们是生活在同一个应用程序中的不同对象。
希望对您有所帮助。
使用serialization/deserializaiton我们可以创建许多导致单例失败的对象。所以为了避免这种情况,我们必须 实现 readResolve() 方法。 在反序列化期间,在提供反序列化对象之前,它将检查 readResolve() 方法。 如果您覆盖并提供单例实例,则不会创建新对象。