public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 2345);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
Map<Integer, Integer> testMap = new HashMap<Integer, Integer>();
testMap.put(1,1);
oos.writeObject(testMap);
oos.flush();
testMap.put(2,2);
oos.writeObject(testMap);
oos.flush();
oos.close();
}
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(2345);
Socket s = ss.accept();
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
System.out.println((HashMap<Integer, Integer>) ois.readObject());
System.out.println((HashMap<Integer, Integer>) ois.readObject());
ois.close;
}
上面的代码来自两个文件。 运行它们时,控制台会打印相同的结果:
{1=1}
{1=1}
这怎么可能发生?
答案 0 :(得分:6)
ObjectOutputStream会记住它已经写入的对象,并且在重复写入时只会输出指针(而不是再次输出内容)。这保留了对象标识,对于循环图是必需的。
所以你的流包含的基本上是:
您需要在案例中使用新的HashMap实例。
答案 1 :(得分:2)
正如Thilo已经说过的那样,ObjectOutputStream
会保留已经编写的内容的缓存。您可以按照他的建议使用新地图,也可以清除缓存。
在writeObject
的调用之间调用ObjectOutputStream.reset
将清除缓存并为您提供原先预期的行为。
public static void main(String[] args) throws IOException,
ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
HashMap<Integer, Integer> foo = new HashMap<>();
foo.put(1, 1);
oos.writeObject(foo);
// oos.reset();
foo.put(2, 2);
oos.writeObject(foo);
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
System.out.println(ois.readObject());
System.out.println(ois.readObject());
}
}