Java 通过ObjectOutputStream发送相同但已修改的对象

Java 通过ObjectOutputStream发送相同但已修改的对象,java,io,objectoutputstream,Java,Io,Objectoutputstream,下面的代码显示了我的一个bug或误解 我发送了相同的列表,但通过ObjectOutputStream进行了修改。一次为[0],另一次为[1]。但当我阅读它时,我得到[0]两次。我认为这是因为我通过同一个对象发送,而ObjectOutputStream必须以某种方式缓存它们 这是工作,因为它应该,还是我应该提交一个错误 import java.io.*; import java.net.*; import java.util.*; public class OOS { public s

下面的代码显示了我的一个bug或误解

我发送了相同的列表,但通过ObjectOutputStream进行了修改。一次为[0],另一次为[1]。但当我阅读它时,我得到[0]两次。我认为这是因为我通过同一个对象发送,而ObjectOutputStream必须以某种方式缓存它们

这是工作,因为它应该,还是我应该提交一个错误

import java.io.*; import java.net.*; import java.util.*; public class OOS { public static void main(String[] args) throws Exception { Thread t1 = new Thread(new Runnable() { public void run() { try { ServerSocket ss = new ServerSocket(12344); Socket s= ss.accept(); ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); List same = new ArrayList(); same.add(0); oos.writeObject(same); same.clear(); same.add(1); oos.writeObject(same); } catch(Exception e) { e.printStackTrace(); } } }); t1.start(); Socket s = new Socket("localhost", 12344); ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); // outputs [0] as expected System.out.println(ois.readObject()); // outputs [0], but expected [1] System.out.println(ois.readObject()); System.exit(0); } } 导入java.io.*; 导入java.net。*; 导入java.util.*; 公共类OOS{ 公共静态void main(字符串[]args)引发异常{ 线程t1=新线程(新的可运行线程(){ 公开募捐{ 试一试{ ServerSocket ss=新的ServerSocket(12344); 套接字s=ss.accept(); ObjectOutputStream oos=新的ObjectOutputStream(s.getOutputStream()); List same=新的ArrayList(); 相同。添加(0); oos.writeObject(相同); 相同。清除(); 相同。添加(1); oos.writeObject(相同); }捕获(例外e){ e、 printStackTrace(); } } }); t1.start(); 套接字s=新套接字(“本地主机”,12344); ObjectInputStream ois=新ObjectInputStream(s.getInputStream()); //按预期输出[0] System.out.println(ois.readObject()); //输出[0],但应为[1] System.out.println(ois.readObject()); 系统出口(0); } }
流有一个引用图,因此发送两次的对象不会在另一端给出两个对象,您只会得到一个。分别发送两次相同的对象将给您两次相同的实例(每个实例都有相同的数据,这就是您所看到的)


如果要重置图形,请参阅reset()方法。

Max是正确的,但也可以使用:

public void writeUnshared(Object obj);

请参阅下面的注释,了解在这种情况下有效的警告,但通常会导致非常奇怪的错误。写入的任何组件对象仍将共享。因此,例如,如果上面的列表是用Collections.synchronizedList包装的,那么问题仍然存在。writeUnshared不是很有用。