需要说明,为什么将Serializable添加到Singleton类是不够的?

时间:2013-10-18 02:16:01

标签: java

任何人都可以向我解释这意味着什么?特别是粗线。

  

要使单例类可序列化,仅仅是不够的   将implements Serializable添加到其声明。保持   单身保证,您必须声明所有实例字段   transient并提供readResolve()方法。否则,每个   对序列化实例进行反序列化的时间,将是一个新实例   创建,在我们的例子中,导致虚假的猫王   目击。要防止这种情况,请将此readResolve()方法添加到   Elvis课程:

// Singleton with static factory
public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() { ... }
    public static Elvis getInstance() { return INSTANCE; }
    public void leaveTheBuilding() { ... }
}

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

仅供参考:这些行来自Effective Java Book,第3项

2 个答案:

答案 0 :(得分:4)

readResolve从流中读取对象并准备将其返回给调用者时,将调用ObjectInputStream方法。 ObjectInputStream检查对象的类是否定义readResolve方法。如果定义了方法,则调用readResolve方法以允许流中的对象指定要返回的对象。

在Singleton的情况下,我们返回在类加载时创建的同一个实例,并且不返回新的实例。所以保持单身性。

答案 1 :(得分:1)

假设您有两个类,它们引用了实例SingletonClass

public class ClassA implements Serializable {

    private SingletonClass s = SingletonClass.getInstance();

}


public class ClassB implements Serializable {

    private SingletonClass s = SingletonClass.getInstance();

}

如果ClassAClassB的每个实例都被序列化然后反序列化,那么它们都将创建SingletonClass的新实例,因为它不是通过getInstance检索的方法,而是从一些持久存储中反序列化。

通过像你一样修改单例类,当你反序列化它时,它将始终返回静态共享实例,因此每个反序列化都将引用INSTANCE