Java套接字/序列化,对象赢得';t更新
我正在写一个基于套接字的小程序。我正在使用类ModelEvent通过套接字传递信息。在ModelEvent中,有一个类型为(Object)的变量obect 对象本身是具有某些值的二维数组Java套接字/序列化,对象赢得';t更新,java,sockets,serialization,Java,Sockets,Serialization,我正在写一个基于套接字的小程序。我正在使用类ModelEvent通过套接字传递信息。在ModelEvent中,有一个类型为(Object)的变量obect 对象本身是具有某些值的二维数组 object[1][2] = 2; ModelEvent event = new ModelEvent("allo", object); dispatchEvent(event); object[2][3] = 2; ModelEvent event2 = new ModelEvent("you", obje
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。第一个事件(event)由客户端接收,数据正确。通过数据发送的第二个事件不正确。其数据与第一次调度中的数据相同。“allo”和“you”是看我是否两次都没有读同一个事件,而答案是没有。字符串是正确的,但如果对象已更新,则对象不是。在发送第二个事件之前,我对数组进行了迭代,以查看它是否在服务器端进行了更新。但在客户端,即使事件本身发生了更改,它仍然与第一次调度中的相同。请参阅
重置将忽略已写入流的任何对象的状态。该状态被重置为与新的ObjectOutputStream
相同。流中的当前点标记为重置,因此相应的ObjectInputStream
将在同一点重置。以前写入流的对象将不会被引用为已在流中。它们将再次写入流中
在写入同一对象之前调用reset,以确保其更新状态已序列化。否则,它将只使用对先前写入的对象及其过期状态的反向引用
或者,您也可以使用以下选项
将“非共享”对象写入ObjectOutputStream
。此方法与writeObject
相同,不同之处在于它总是将给定对象作为流中新的唯一对象写入(与指向先前序列化实例的反向引用相反)
具体而言:
- 通过writeUnshared写入的对象始终以与新出现的对象(尚未写入流的对象)相同的方式序列化,而不管该对象之前是否已写入
- 如果使用
写入以前使用writeUnshared写入的对象,则以前的writeUnshared操作将被视为是对单独对象的写入。换句话说,writeObject
永远不会生成对调用ObjectOutputStream
写入的对象数据的反向引用writeUnshared
writeUnshared
写入对象本身并不能保证反序列化时对对象的唯一引用,但它允许在流中多次定义单个对象,因此接收方对readUnshared
的多次调用不会冲突。请注意,上述规则仅适用于使用writeUnshared
编写的基本级别对象,而不适用于要序列化的对象图中任何传递引用的子对象
请注意,这是一个很好的实践
从ObjectInputStream
读取“非共享”对象。此方法与readObject相同,只是它防止后续对readObject
和readUnshared
的调用返回对通过此调用获得的反序列化实例的其他引用
具体而言:
- 如果调用
来反序列化反向引用(之前已写入流的对象的流表示),将抛出readUnshared
ObjectStreamException
- 如果
成功返回,则任何后续尝试反序列化由readUnshared
反序列化的流句柄的引用都将导致抛出readUnshared
ObjectStreamException
readUnshared
反序列化对象会使与返回对象关联的流句柄无效。注意,这本身并不总是保证readUnshared
返回的引用是唯一的;反序列化对象可以定义readResolve
方法,该方法返回对其他方可见的对象,或者readUnshared可以返回流中其他地方或通过外部手段可获得的Class
对象或enum
常量。如果反序列化对象定义了readResolve
方法,并且调用该方法返回一个数组,则readUnshared
返回该数组的浅克隆;这保证了返回的数组对象是唯一的,并且不能通过调用readObject
或在ObjectInputStream
上的readUnshared第二次获得,即使底层数据流已被操作
我没有看到dispatchEvent代码,但根据您编写的代码,我假设: 您写入同一对象(仅其状态更改),这意味着它将只写入引用两次。您可以在java输出流文档中看到(关于性能) 您应该使用writeUnshared(),它将在每次写入时创建一个新对象
我知道有人建议重置,这将使您获得相同的结果,但它会影响性能。您如何在客户端阅读它?ObjectInputStream.readObject和我正在播放它我现在想吻您!不用了,谢谢。只是为了理解,当一个对象被发送两次到流时,它会记住它以前的状态并使用旧状态?是的,它会:)!我认为这是出于性能原因,但它不适合你想使用它。回答得好。我调试了100次我的代码,我认为我做错了什么,我只需要重置()流感谢你+1指出了性能影响。当你发布时,我修改了我的答案,加入了
writeUnshared
。-1表示“性能影响”。writeUnshared()和
/* prevent using back references */
output.reset();
output.writeObject(...);
output.writeUnshared(...);
obj = input.readUnshared();