为何修改对象属性后写入文件不生效?Java序列化问题
问题原因
Java的ObjectOutputStream内部维护了一个对象引用注册表,当你第一次写入某个对象实例后,后续再写入同一个对象引用时,不会重新序列化对象的当前状态,只会写入一个指向之前已序列化对象的引用标识。
你的代码里两次写入的是同一个obj对象引用,第二次修改val后调用writeObject时,实际只写入了引用标记,并没有序列化修改后的对象状态。读取时,两次readObject都会解析为第一次序列化的那个对象实例,所以输出的val都是1。
解决方法
有两种常用的解决方式:
方式一:写入新的对象实例
每次写入时创建新的MyObj实例,确保每次序列化的是不同的对象引用:
public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.txt")); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.txt")); MyObj obj1 = new MyObj(); obj1.val = 1; oos.writeObject(obj1); MyObj obj2 = new MyObj(); obj2.val = 2; oos.writeObject(obj2); System.out.println( ((MyObj)ois.readObject()).val ); // 输出1 System.out.println( ((MyObj)ois.readObject()).val ); // 输出2 oos.close(); ois.close(); }
方式二:重置对象输出流的引用注册表
在第二次写入对象前,调用oos.reset()方法清空之前的引用记录,让ObjectOutputStream重新序列化当前对象的状态:
public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.txt")); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.txt")); MyObj obj = new MyObj(); obj.val = 1; oos.writeObject(obj); obj.val = 2; oos.reset(); // 重置引用表,清除之前的对象记录 oos.writeObject(obj); System.out.println( ((MyObj)ois.readObject()).val ); // 输出1 System.out.println( ((MyObj)ois.readObject()).val ); // 输出2 oos.close(); ois.close(); }
内容的提问来源于stack exchange,提问作者troy
相关产品推荐
相关产品推荐

