Java 串行化单例的瞬态
有效的Java—为了维护单例保证,您 必须声明所有实例字段,并提供“readResolve”方法。 我们通过在这里声明字段来实现什么? 以下是一个示例:Java 串行化单例的瞬态,java,singleton,Java,Singleton,有效的Java—为了维护单例保证,您 必须声明所有实例字段,并提供“readResolve”方法。 我们通过在这里声明字段来实现什么? 以下是一个示例: .... .... public final class MySingleton implements Serializable{ private int state; private MySingleton() { state =15; } private static final MySingleton INSTANCE = new
....
....
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()getign打印为25。
我在这里遗漏了什么吗?通过使属性为transient而获得的好处是没有序列化状态。序列化它是不必要的,因为readResolve()方法无论如何都会丢弃它 如果状态包含在一个int中,那就无关紧要了。但是,如果状态是一个复杂的对象图,则会产生显著的性能差异。当然,如果状态是不可序列化的,那么您没有其他选择 也就是说,序列化一个单例是有问题的 不管我是否将“state”变量声明为transient,我都会将c.getState()getign打印为25。我是不是遗漏了什么 替换反序列化对象,因为readResolve()返回MySingleton的私有静态实例,从而覆盖反序列化返回的实例
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 正如我所提到的,“状态”是否是暂时的,结果也没有什么不同。