I had a small problem today where I needed to refactor a Java class and maintain its serialization identity. I guessed that if I maintained the class's instance variable order and explicitly defined the serialVersionUID class variable with the class's previous implicit value I would be safe. So, before refactoring, I used Java's serialver to get the class's serialVersionUID. I then refactored the class and added the serialVersionUID class variable. But it didn't work. What was wrong? I needed to look into the object's serialization.
An object's serialized form is defined in Java Object Serialization Specification. I really didn't want to read the specification: All that I really wanted was to see the differences between the class's pre-refactor stream and the post-refactor stream. So I used jdeserialize to dump the protocol encoding of the streams.
What was quickly apparent in the dump was that the order of the instance variables within the stream have no relation to their order in the class definition. I was not expecting this. During the refactoring I had renamed some instance variables to better reflect their purpose. Once I reverted the instance variable's names to their previous values the serialization was the same. Success.
A distressing aspect of this exploration was that two objects with the same serialVersionUID will be considered the same by the serialization implementation and so it will misinterpret the bytes in the stream for the bytes needed by the class. The end result is that you get an object that is initialized wrong. I would have expected an exception that indicated the mismatch between data in the stream and data expected by the class. Perhaps there is a command line switch or system property I can use to enforce a stricter pairing. Be very careful when refactoring a class with an explicit serialVersionUID to either remove or update its value before committing the changes.