有效的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();
}
}
}
无论我是否将'state'变量声明为transient,我都将c.getState()gettign打印为25。 我在这里错过了什么吗?
答案 0 :(得分:2)
通过使属性瞬态获得的是您不会序列化状态。序列化它是不必要的,因为它无论如何都被readResolve()方法丢弃。
如果状态包含int,则无关紧要。但是如果状态是一个复杂的对象图,它会产生显着的性能差异。当然,如果状态不可序列化,则您没有其他选择。
那就是说,序列化一个单身人士是值得怀疑的。
答案 1 :(得分:0)
无论我是否将'state'变量声明为瞬态变量,我都将c.getState()gettign打印为25.我在这里遗漏了什么?
替换反序列化对象,因为readResolve()返回MySingleton的私有静态实例,从而覆盖反序列化返回的实例。
答案 2 :(得分: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岁?