0

有效的 Java - 为了保持单例保证,您必须声明所有实例字段瞬态并提供“readResolve”方法。通过在这里声明字段瞬态我们可以实现什么?这是一个示例:

....
....
public final class MySingleton implements Serializable{
 private int state;
 private MySingleton() { state =15; }
 private static final MySingleton INSTANCE = new MySingleton();
 public static MySingleton getInstance() { return INSTANCE; }
 public int getState(){return state;}
public void setState(int val){state=val;}
private Object readResolve() throws ObjectStreamException {
  return INSTANCE; 
 }
    public static void main(String[] args) {
        MySingleton  c = null;
        try {
            c=MySingleton.getInstance();
            c.setState(25);
            FileOutputStream fs = new FileOutputStream("testSer.ser");
            ObjectOutputStream os = new ObjectOutputStream(fs);
            os.writeObject(c);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            FileInputStream fis = new FileInputStream("testSer.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            c = (MySingleton) ois.readObject();
            ois.close();
            System.out.println("after deser: contained data is " + c.getState());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

无论我是否将“状态”变量声明为瞬态,我都会将 c.getState() gettign 打印为 25。我在这里遗漏了什么吗?

4

3 回答 3

2

通过使属性瞬态获得的是您不会序列化状态。序列化它是不必要的,因为它无论如何都会被 readResolve() 方法丢弃。

如果状态包含在 int 中,则无关紧要。但是,如果状态是对象的复杂图,则会产生显着的性能差异。当然,如果状态是不可序列化的,你别无选择。

也就是说,序列化单例是有问题的。

于 2013-04-05T13:36:31.150 回答
0

无论我是否将“状态”变量声明为瞬态,我都会将 c.getState() gettign 打印为 25。我在这里遗漏了什么吗?

您替换了反序列化的对象,因为 readResolve() 返回了 MySingleton 的私有静态实例,从而覆盖了反序列化返回的实例。

于 2013-04-05T13:56:00.113 回答
0
try {
            c=MySingleton.getInstance();
            c.setState(25);
            FileOutputStream fs = new FileOutputStream("testSer.ser");
            ObjectOutputStream os = new ObjectOutputStream(fs);
            os.writeObject(c);
            os.close();
 }

您得到 25 是因为您在对象中设置了该值。参考上面的代码。我想你期望答案是 15?

于 2014-02-20T18:49:23.877 回答