Search code examples
javaserializationdefault

Preventing Java serialization setting default values


I have a serialized object MyObject that contains integer foo. I set a value 10 to integer foo and save the object to a file using writeObject().

I add integer bar to object MyObject. I set a value 15 to integer bar and then load the old serialized file using readObject().

The old serializable file doesn't contain integer bar so integer bar will get value 0. I want to keep the value 15 in bar if the old serializable file doesn't contain variable bar.

Should I override readObject() or how could I prevent readObject() from setting "default values" to unknown objects?

I want to do this because in the constructor I'm setting my own default values and would like to use my own default values to control versioning.


Solution

  • Serialization doesn't set default values it defers to Java's default value initialization scheme.

    If I can sum up your question. You want serialization to merge what's in the serialized stream with the values in memory. That's not possible with Java serialization as it controls what objects to create. You can read in your serialized object, then manually write the code to merge what fields you want merged together. If your stuck on Java serialization (I'd steer clear of it if I were you), but let's say you want to continue using it.

    public class MyObject {
    
        public void merge( MyObject that ) {
            // given some other instance of an object merge this with that.
            // write your code here, and you can figure out the rules for which values win.
        }
    }
    
    ObjectInputStream stream = new ObjectInputStream( new FileInputStream( file ) );
    MyObject that = stream.readObject();
    someObject.merge( that );
    

    Viola you control which fields will be merged from that into someObject. If you want a library to do this merge for you check out http://flexjson.sourceforge.net. It uses JSON serialization, and works from Beans rather than POJO. However, there is a way to take an already populated object and overwrite values from a JSON stream. There are limitations to this. The other benefit of this is you can actually read the stream back AFTER your object structure has changed something that Java serialization can technically do, but its very very hard.