如何重新序列化已修改对象?Java重复序列化不生效问题求助
解决Java重复序列化同一对象后反序列化无法获取更新值的问题
问题根源
Java的ObjectOutputStream内部维护着一个已序列化对象的缓存:第一次调用writeObject序列化某个对象时,该对象会被存入缓存;后续再调用writeObject序列化同一个对象引用时,并不会重新序列化对象的最新状态,仅会写入一个指向缓存中原有对象的引用。这就是修改对象后再次序列化,反序列化仍得到旧值的原因。
解决方案
无需创建新实例或新文件,只需在修改对象并再次序列化前,调用ObjectOutputStream.reset()方法清空缓存。该方法会重置输出流状态,清除之前缓存的所有对象,让下一次writeObject重新序列化当前对象的最新状态。
修改后的代码
public class A implements Serializable { private static final long serialVersionUID = 1L; private int field; public static void main(final String[] args) throws Exception { final ObjectOutputStream writer = new ObjectOutputStream(new FileOutputStream("serialized_object.bin")); final ObjectInputStream reader = new ObjectInputStream(new FileInputStream("serialized_object.bin")); final A obj = new A(); obj.field = 2; writer.writeObject(obj); final A deserialized1 = (A) reader.readObject(); System.out.println("first deserialized's field: " + deserialized1.field); obj.field = 3; // 重置输出流缓存,清除已序列化的对象引用 writer.reset(); writer.writeObject(obj); final A deserialized2 = (A) reader.readObject(); System.out.println("second deserialized's field: " + deserialized2.field); writer.close(); reader.close(); } }
可选方案:使用writeUnshared()
如果不想每次调用reset(),也可以用writeUnshared()替代writeObject()。该方法不会将对象加入输出流缓存,每次调用都会序列化当前对象的状态,但反序列化时需要对应使用readUnshared():
// 序列化部分 obj.field = 2; writer.writeUnshared(obj); // ... obj.field = 3; writer.writeUnshared(obj); // 反序列化部分 final A deserialized1 = (A) reader.readUnshared(); // ... final A deserialized2 = (A) reader.readUnshared();
验证结果
修改后运行程序,输出将符合预期:
first deserialized's field: 2
second deserialized's field: 3
内容的提问来源于stack exchange,提问作者Alvin Kim
相关产品推荐
相关产品推荐

