I just came across "WTF" sort of error: I updated one of my classe's methods and added one method too. After running my program, this is what popped our when program tried to open and unserialize recently saved data (before the methods changes):
java.io.InvalidClassException: cz.autoclient.settings.Settings; local class incompatible: stream classdesc serialVersionUID = 2404650814140543454, local class serialVersionUID = 4256355437298300223
According to what java documentation says about that, java methods are not being serialized. So why does the serialVersionUID
take class methods in account too?
Since Java programmers seem to be so mad about using getters and setters literally everywhere, why is it not possible to create getter for serialVersionUID
so that I can implement my own algorithm that only calculates the properties?
The serialVersionUID
can be overriden, but only with static final long serialVersionUID
value which would require me to remember to change it when I change class's properties.
The Oracle docs indicate that if you do not provide a
serialVersionUID
, the compiler will generate one for you.And according to the Java Object Serialization Specification section 5.1
What's happening here is that the compiler has decided the difference between the two versions of your code warrant a new
serialVersionUID
. If you feel that the state contained in an instance of Object(1) and Object(2) are interchangeable, you should manage this by setting theserialVersionUID
manually and keeping it the same between those changes.Yes, you will have to manually manage this, and change it when you make changes to the mechanisms which manage the internal state of the class.
As a note though, if the public methods have changed, you should consider if the original version of the class meets the same expectations as the new version. If you would like the data contained in the previously-serialized state to be loaded into a new version of the class, perhaps use a static constructor method to initialize the new version (new behavior) with the compatible, old state.
Based on the documentation for java, they recommend to use custom
serialVersionUID
as much as possible, because the default algorithm will take class implementation details and the result is said to vary from JVM implementation to another.The default algorithm used by Java to generate the
serialVersionUID
seems to be considering the non-private methods (step 7) as well. Which explains the exception if you were using the defaultserialVersionUID
in your implementation.EDIT: As you suggested, it would be great if we can have our own implementation of a method to do this, rather than overriding the
serialVersionUID
as astatic final long
. But I guess they don't allow that because if it were allowed, wrong implementations of such a method could invalidate the whole purpose of theserialVersionUID
.