一尘不染

Java套接字/序列化,对象不会更新

java

我正在写一个基于套接字的程序。我正在使用ModelEvent类通过套接字传递信息。在ModelEvent中,有一个类型为(Object)的变量对象。

对象本身是带有某些值的2D数组。

object[1][2] = 2;
ModelEvent event = new ModelEvent("allo", object);
dispatchEvent(event);

object[2][3] = 2;
ModelEvent event2 = new ModelEvent("you", object);
dispatchEvent(event2);

假设数组对象填充了值1。第一个事件(事件)由客户端接收,并且数据正确。通过数据发送的第二个事件不正确。其数据与第一次调度中的数据相同。“ allo”和“ you”是要查看我是否两次都没有读取同一事件,而答案是否定的。如果已更新字符串,则该字符串是正确的,但该对象不是该事件。我在发送第二个事件之前遍历数组,以查看它是否在服务器端被更新了。但是在客户端,即使事件本身已更改,它仍然与第一次调度中的相同。


阅读 338

收藏
2020-03-18

共1个答案

一尘不染

请参阅ObjectOutputStream.reset

重置将忽略任何已写入流的对象的状态。状态被重置为与new相同ObjectOutputStream。流中的当前点被标记为重置,因此相应的ObjectInputStream点将在同一点重置。先前写入流中的对象将不会被视为已经存在于流中。它们将再次写入流中。

/* prevent using back references */
output.reset();
output.writeObject(...);

在写入同一对象之前,请调用reset以确保其更新状态被序列化。否则,它将仅使用对先前写入的对象及其过期状态的反向引用。

或者,你也可以使用ObjectOutputStream.writeUnshared以下方法。

将“非共享”对象写入ObjectOutputStream。此方法与相同writeObject,除了它始终将给定对象写为流中新的唯一对象(与指向先前序列化实例的反向引用相反)。

特别:

通过writeUnshared写入的对象始终以与新出现的对象(尚未写入流的对象)相同的方式进行序列化,而不管该对象先前是否已写入。

如果writeObject用于写入先前使用writeUnshared写入的对象,则将先前的writeUnshared操作视为对单独对象的写入。换句话说,ObjectOutputStream将永远不会产生对通过调用写入的对象数据的反向引用writeUnshared

虽然通过写入对象writeUnshared本身并不能保证对对象进行反序列化时可以唯一引用该对象,但是它允许在流中多次定义单个对象,从而使readUnshared接收方进行的多次调用不会冲突。请注意,上述规则仅适用于用编写的基本级对象writeUnshared,不适用于要序列化的对象图中任何可传递引用的子对象。

output.writeUnshared(...);

请注意,与结合使用是一种好习惯ObjectInputStream.readUnshared

从中读取一个“非共享”对象ObjectInputStream。此方法与readObject相同,不同之处在于,它防止后续调用readObjectreadUnshared返回对通过此调用获得的反序列化实例的附加引用。

特别:

如果readUnshared调用来反序列化反向引用(先前已写入流的对象的流表示形式),ObjectStreamException则将抛出an
如果readUnshared成功返回,则随后对反序列化反序列化的流引用进行反序列化的任何尝试readUnsharedObjectStreamException将引发。
通过反序列化对象readUnshared会使与返回的对象关联的流句柄无效。注意,这本身并不总是保证由返回的引用readUnshared是唯一的。反序列化的对象可以定义一个readResolve返回对其他方可见的对象的方法,或者readUnshared可以返回在流中其他位置或通过外部手段可获得的Class对象或enum常量。如果反序列化的对象定义了一个readResolve方法,并且对该方法的调用返回了一个数组,则readUnshared返回该数组的浅表副本;这保证了返回的数组对象是唯一的,并且无法通过调用readObjectreadUnshared再次获得该数组对象。ObjectInputStream,即使底层数据流已被操纵。

obj = input.readUnshared();
2020-03-18