I have some serialised objects from a class that looks like:
I have since decided that number needs to be a Long. I know that I can't just change it, as that will break deserialisation for my existing objects. So I do the following:
So now, newly made objects will exclusively use newNumber to store the value, and leave number null, and existing classes that I deserialise, get/set from, and then serialise again, will have their value copied over to newNumber.
My question is... is it safe to remove the Integer number field, once I know that all my stored objects have been migrated over to use the new field? e.g. does deserialision break even if the value it's attempting to set is null?
Any changes to the fields will change the serialVersionUID, and so make serialization impossible from "old" instances to "new", unless ...
You explicitly set the serialVersionUID, as you did, which effectively disables this check. By the way, you don't have to set it to such a cryptic number, unless you're trying to match it with a version of the class that didn't explicitly set the value. Normally, you can just set it to 0 or 1 or whatever. Not everyone knows that.
So, now we can serialize between different versions of the code:
Any member data that is present in the class available to the deserializer, but not in the serialized object will be set to a default value. (null, 0, or false)
Any values present in the serialized object, but not in the member data will be discarded.
So, I think that answers your question, but I agree with Paul that you should just run it through some tests. After all, my memory could be faulty, or serialization might have changed in the 14 years since I last looked into in that level of detail. Incidentally, you might look into the weird private methods readObject() and writeObject(). They can be useful for converting between different object versions. I'm not sure if they could help you in this case though.