java - (java) ObjectInputStream反序列化对象的错误版本

标签 java serialization objectinputstream

<分区>

我只是从一本 Java 书上学习网络,所以我有点菜鸟。我在书上和网上都找不到这个问题,所以我决定上网问问。

书上说使用 ObjectOutputStream 和 ObjectInputStream 向不同的控制台发送和接收对象。

现在,我能够成功接收我发送的对象——但只能接收一次。当我发送不同的对象时:随机字符串和整数以及无名实例,控制台具有所有正确的字段。但是,当我发送对象的实例、更改实例字段之一的值并重新发送对象时,inpustream 会加载原始实例的值。

因此,举例来说,我有一个类的实例,其 public int“var”等于 1。如果我发送此类的实例,客户端会收到它并正确报告 var = 1。但是,如果我将 var 更改为 2(在同一个实例中)并重新发送它,客户端将完成调用 read() 方法(因此它一定已经收到新对象!),但它会报告 var 为 1。如果我发送将实例发送给尚未收到该实例的不同客户端,它将正确地将 var 报告为 2,并且即使我更改了 var,它也会继续将其报告为 2。

客户端读取正确版本的实例(如果之前未收到实例)这一事实必须意味着该对象正在通过输出流正确发送;由于某种原因,输入流无法正常工作。它几乎就像它看到它是同一个对象,所以它假设它具有相同的值而不检查。为什么会发生这种情况,我该如何解决?

抱歉,如果我问了一些愚蠢的问题——这本书没有解释序列化和套接字是如何工作的,只是如何使用它们,所以我很可能从根本上对如何使用它们感到困惑。谢谢!

我为测试问题编写的简单代码:

服务器:(有一个定时器 Action 来持续发送更新的对象)

    public void actionPerformed(ActionEvent e)
{
    object.var++;
            output.write(object);
            output.flush();
            System.out.println(object.var);
}

客户端

    public void run()
{
    while(true)
            {
                   Test t = (Test)input.readObject();
                   System.out.println(t.var);
            }
    }

当这些程序运行时,Server 类的输出是 1,2,3,4... 无限增加,而 Client 类的输出只是 1,1,1,1,1,1,1,etc。

感谢您花时间阅读本文。对不起,如果我只是愚蠢,我是新手。

编辑:抱歉,read() 打错了(我手动输入了代码,因为我无法正确设置格式),我的意思是 input.readObject()

最佳答案

原因是 ObjectOutputStream 缓存对象引用,如果同一对象被写入两次,则将反向引用写入流。这意味着当您第二次调用 write 时,流实际上并没有写入对象的新副本,它只是插入对已写入对象的引用。

您可以通过在写入调用之间调用 ObjectOutputStream.reset 来防止这种情况。这告诉流丢弃任何缓存的引用。

这种行为看起来很奇怪,但如果您尝试序列化具有循环引用的对象图(即编写引用对象 B 的对象 A,对象 B 又引用回对象 A),则实际上有必要防止无限循环。

关于java - (java) ObjectInputStream反序列化对象的错误版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6352540/

相关文章:

java - 在 JUnit 中测试 CharSequences 是否相等

java - 为什么 Java Spring v.2.2.7 不支持请求方法 'POST'?

java - 使用 ThriftData 以 Avro 格式序列化 Thrift 数据时出现 ClassCastException

java - 测试实现 java.lang.Serializable 的类以确保任何更改都向后兼容

Python原始json字符串序列化

java - 安卓/Java : How to track progress of InputStream

java - 如何用多个分隔符分隔字符串?

java - 使用 JPA native 查询和 MemSql 选择 json 列

java - 这是好的做法吗 - 使用 EOF 异常来检测文件结尾

java - ObjectInputStream 抛出 NotSerializedException