Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java套接字/序列化,对象赢得';t更新_Java_Sockets_Serialization - Fatal编程技术网

Java套接字/序列化,对象赢得';t更新

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

我正在写一个基于套接字的小程序。我正在使用类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", object);
dispatchEvent(event2);
假设数组对象中填充了值1。第一个事件(event)由客户端接收,数据正确。通过数据发送的第二个事件不正确。其数据与第一次调度中的数据相同。“allo”和“you”是看我是否两次都没有读同一个事件,而答案是没有。字符串是正确的,但如果对象已更新,则对象不是。在发送第二个事件之前,我对数组进行了迭代,以查看它是否在服务器端进行了更新。但在客户端,即使事件本身发生了更改,它仍然与第一次调度中的相同。

请参阅

重置将忽略已写入流的任何对象的状态。该状态被重置为与新的
ObjectOutputStream
相同。流中的当前点标记为重置,因此相应的
ObjectInputStream
将在同一点重置。以前写入流的对象将不会被引用为已在流中。它们将再次写入流中

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

或者,您也可以使用以下选项

将“非共享”对象写入
ObjectOutputStream
。此方法与
writeObject
相同,不同之处在于它总是将给定对象作为流中新的唯一对象写入(与指向先前序列化实例的反向引用相反)

具体而言:

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

  • 如果使用
    writeObject
    写入以前使用writeUnshared写入的对象,则以前的writeUnshared操作将被视为是对单独对象的写入。换句话说,
    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();