【问题标题】:Object property change is not saved after streaming in java在java中流式传输后未保存对象属性更改
【发布时间】:2014-11-19 00:38:13
【问题描述】:

更新: 好的,所以我已经将部分代码变灰并找到了导致问题的原因。 我在这里添加了 3 行代码,并带有注释“这是导致问题的添加代码”。

但我还是不明白为什么会影响结果。

我正在开发一个通过 ObjectOutputStream 和 ObjectInputStream 发送数据对象的客户端-服务器应用程序。

我注意到一些奇怪的东西,让我觉得我可能没有完全理解对象引用。

在客户端,我有一个创建并返回用户对象的方法:

private static User createNewUser()
{
    User newUser = new User();

    newUser.name = "Jim";
    newUser.phone = "054-6885644";
    ..

    return newUser;
}

我使用此方法创建了一个用户对象,更改其属性之一并将其发送到服务器:

User user = createNewUser();

out.writeObject(user); // this is the added code that causes the problem
out.flush(); // this is the added code that causes the problem

system.out.println("old phone number: " + user.phone); // this prints out 054-6885644
user.phone = "052-9008801";
system.out.println("new phone number: " + user.phone); // this prints out 052-9008801

out.writeObject(user);
out.flush();

在服务器端我读取了对象:

User user = (User) in.readObject(); // this is the added code that causes the problem

User newProfile = (User) in.readObject();
System.out.println("phone number: " + newProfile.phone); // this prints out 054-6885644 (why??)

因此,如您所见,在我流式传输对象之前,属性已更新。但是服务器反序列化后,得到的是原来的属性值。 这是为什么呢?

顺便说一句,我尝试在流式传输之前克隆对象(创建一个完全不同的对象并仅复制字段)并且它起作用了 - 属性值没有恢复。

那么为什么会这样呢?为什么流式传输后对引用对象属性的更改没有保存?

【问题讨论】:

  • 我在我的系统上复制了这个,使用 2 个不同的项目,服务器打印出新号码。请创建一个产生相同问题的MCVE,以确保您可能正在编写的其他代码不会出现问题。
  • @VinceEmigh,感谢您的评论。我添加了复制问题的 3 行代码。
  • 通过流发送的对象被缓存。当您第二次发送对象时,我相信 OOS 正在使用缓存值而不是具有新电话值的对象。在第二次发送对象之前尝试调用out.reset()。如果这可行,请告诉我,我把它作为答案
  • @VinceEmigh,这确实解决了问题。谢谢!

标签: java io objectoutputstream


【解决方案1】:

当您使用writeObject(Object) 输出对象时,实例将被序列化(如预期的那样)。问题是,序列化版本将被缓存,并且任何时候您尝试再次写入同一个实例时,都会引用序列化实例的缓存版本。

为避免这种情况,您可以在调用writeObject(Object) 后调用reset(),也可以使用writeUnshared(Object)

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    相关资源
    最近更新 更多