Object property change is not saved after streamin

2019-01-20 03:28发布

问题:

Update: OK so I've grayed out parts of code and found what was causing the problem. I've added here 3 lines of code with the comment "this is the added code that causes the problem".

But I still don't understand why it affects the result.

I am working on a client-server application that sends data objects via ObjectOutputStream and ObjectInputStream.

I noticed something strange that made me think I might not fully understand object referencing.

On the client side I have a method that creates and returns a User object:

private static User createNewUser()
{
    User newUser = new User();

    newUser.name = "Jim";
    newUser.phone = "054-6885644";
    ..

    return newUser;
}

I create a User object using this method, change one of its properties and send it to the server:

User user = createNewUser();

out.writeObject(user); // this is the added code that causes the problem
out.flush(); // this is the added code that causes the problem

system.out.println("old phone number: " + user.phone); // this prints out 054-6885644
user.phone = "052-9008801";
system.out.println("new phone number: " + user.phone); // this prints out 052-9008801

out.writeObject(user);
out.flush();

On the server side I read the object:

User user = (User) in.readObject(); // this is the added code that causes the problem

User newProfile = (User) in.readObject();
System.out.println("phone number: " + newProfile.phone); // this prints out 054-6885644 (why??)

So, as you can see, before I stream the object, the propery was updated. But after the server deserializes it, it gets the original property value. Why is that?

By the way, I tried cloning the object before streaming it (creating an entirely different object and just copying the fields) and it worked - the propery value did not revert.

So why is this happening? Why does the change to the referenced object's property not saved after streaming?

回答1:

When you output an object using writeObject(Object), the instance will be serialized (as expected). The problem is, the serialized version will be cached, and any time you attempt to write that same instance a second time, the cached version of the serialized instance is referenced.

To avoid this, you can either call reset() after calling writeObject(Object), or you could use writeUnshared(Object)