Click to See Complete Forum and Search --> : Write Object Anomaly


zugzwang
November 22nd, 2004, 05:00 PM
/*
In main()
1. myPet(Bosco) written to output stream o1.
2. myPet name changed to Lassie
3. myPet(Lassie) again written to o1.
4. myPet(Lassie) written to new output stream o2.

I would expect output to be:

out1Write1: [Bosco]
out1Write2: [Lassie]
out2Write1: [Lassie]

Instead output is:

out1Write1: [Bosco]
out1Write2: [Bosco]
out2Write1: [Lassie]

Why isn't out1Write2 = Lassie?
*/

import java.io.*;

class Animal implements Serializable {
private String name;
Animal(String n) { name = n; }
public void chgName(String s) { name = s; }
public String toString() { return ("[" + name + "]"); }
}

public class WriteObjectAnomaly {
public static void main(String[] args) throws Exception {
Animal myPet = new Animal("Bosco");
ByteArrayOutputStream buf1 = new ByteArrayOutputStream();
ObjectOutputStream o1 = new ObjectOutputStream(buf1);
o1.writeObject(myPet);

myPet.chgName("Lassie");
o1.writeObject(myPet);

ByteArrayOutputStream buf2 = new ByteArrayOutputStream();
ObjectOutputStream o2 = new ObjectOutputStream(buf2);
o2.writeObject(myPet);

ObjectInputStream in1 = new ObjectInputStream(
new ByteArrayInputStream(buf1.toByteArray()));
ObjectInputStream in2 = new ObjectInputStream(
new ByteArrayInputStream(buf2.toByteArray()));
Animal out1Write1 = (Animal)in1.readObject();
Animal out1Write2 = (Animal)in1.readObject();
Animal out2Write1 = (Animal)in2.readObject();
System.out.println("out1Write1: " + out1Write1);
System.out.println("out1Write2: " + out1Write2);
System.out.println("out2Write1: " + out2Write1);
}
}

randomjunk
November 23rd, 2004, 03:33 AM
The ObjectOutputStream tries to be clever -- it will only write an object to the stream once. This is so that when you have a list or array or similar and have the same object mentioned in multiple locations or a nice graph structure, the reconstituted objects will have the exact same structure.
Unfortunately this means that writing an object, then changing its state, then trying to write it again results in the code deciding it doesn't need to.

In other words: ObjectOutputStreams are designed to capture a snapshot of your objects at a particular moment in time and not for tracking changes to objects over time.

So you have 3 options that I can see:
1) Rewrite code to create new instances of objects to write
2) Implement a custom data stream to handle your needs
3) Use multiple object streams to represent state at different times

cjard
November 23rd, 2004, 05:55 AM
call ObjectOutputStream.reset() to make it forget about all the objects it has written..