You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何修改对象属性后写入文件不生效?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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:30:55