3

谁能向我解释这是什么意思?尤其是粗线。

要使单例类可序列化,仅仅添加到它的声明是不够implements Serializable的。要维护单例保证,您必须声明所有实例字段 transient并提供readResolve()方法。否则,每次反序列化序列化实例时,都会创建一个新实例,在我们的示例中,这会导致虚假的 Elvis 目击事件。为了防止这种情况,将此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,Item 3

4

2 回答 2

4

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

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

于 2013-10-18T02:48:02.697 回答
1

假设您有两个引用该实例的类SingletonClass

public class ClassA implements Serializable {

    private SingletonClass s = SingletonClass.getInstance();

}


public class ClassB implements Serializable {

    private SingletonClass s = SingletonClass.getInstance();

}

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

通过像你一样修改单例类,当你反序列化它时,它总是会返回静态共享实例,所以每次反序列化都会引用INSTANCE

于 2013-10-18T02:19:44.767 回答