3
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;
}

The code above is from two files. When running them, the console prints the same result:

{1=1}
{1=1}

How can this happen?

wattostudios
  • 8,666
  • 13
  • 43
  • 57
JustFF
  • 115
  • 1
  • 1
  • 6

2 Answers2

6

An ObjectOutputStream remembers the objects it has written already and on repeated writes will only output a pointer (and not the contents again). This preserves object identity and is necessary for cyclic graphs.

So what your stream contains is basically:

  • HashMap A with contents {1:1}
  • pointer: "HashMap A again"

You need to use a fresh HashMap instance in your case.

Thilo
  • 257,207
  • 101
  • 511
  • 656
2

As Thilo already said, an ObjectOutputStream keeps a cache of things it has written already. You can either use a fresh map as he suggests, or clear the cache.

Calling ObjectOutputStream.reset between the calls to writeObject will clear the cache and give you the behavior you originally expected.

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());
    }
}
Community
  • 1
  • 1
Jeffrey
  • 44,417
  • 8
  • 90
  • 141