ObjectStream中Mutable对象的效果

时间:2018-02-14 18:09:14

标签: java stream mutable

我正在尝试使用从Socket获取的ObjectInputStream和ObjectOutputStream在客户端和服务器之间发送数据包。然而,我在尝试向流中发送一个对象时得到了一些奇怪的结果,我的类结构看起来有点如下:

public class Packet {
  public Foo foo;
}

public class Foo {
  public float hp = 100;
  public double mass = 10;
  public void takeDamage(float dmg) {
    hp -= dmg;
    Packet p = new Packet();
    p.foo = this;
    //code to send packet to server
  }
}

但是我发现服务器在到达时会收到不同的Foo值 - 质量总是正确接收但是hp(每秒最多可以改变50次)未被正确接收(通常会被接收到大约97,不管原始对象的实际hp)。我已经在发送数据包之前检查了hp的值,一旦它到达它似乎只是随机改变,但我认为这可能是因为p.foo是一个指针,就像我反而改为做一个深刻的副本:

p.foo = new Foo();
p.foo.hp = hp;
p.foo.mass = mass;

代码似乎通过hp完全正常发送,因此Streams必须传递未发生变异的对象吗?有没有什么好方法可以在java中强制执行此操作?

1 个答案:

答案 0 :(得分:1)

我写的关于ObjectOutpuStream的所有内容也发生在ObjectInputStream

ObjectOutputStream缓存先前序列化的数据,如果再次序列化相同的实例,则只发送引用而不是整个数据。这使得可以序列化循环数据结构而不会陷入无限循环。我想是因为这就是为什么你会收到一个不同的值(很可能是序列化的第一个值)而不是当前值。

出于同样的原因,您迟早会遇到OutOfMemoryError,因为ObjectOutputStream的内部缓存会变得越来越大(您可以调用reset)。

所以我想你可以通过使用不同于ObjectOutputStream的东西来改变你的实现,或者在发送一些东西之后你实例化一个新的ObjectOutputStream(你也需要在接收方那样做)。