问题
I have noticed that some of my serialized objects stored in Redis have problems deserializing.
This typically occurs when I make changes to the object class being stored in Redis.
I want to understand the problem so that I can have a clear design for a solution.
My question is, what causes deserialization problems? Would a removal of a public/private property cause a problem? Adding new properties, perhaps? Would a adding a new function to the class create problems? How about more constructors?
In my serialized object, I have a property Map, what if I change (updated some properties, added functions, etc) myObject, would it cause a deserialization problem?
回答1:
what causes deserialization problems?
I would like to give you bit of background before answering your question,
The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException.
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, It uses the following information of the class to compute SerialVersionUID,
- The class name.
- The class modifiers written as a 32-bit integer.
- The name of each interface sorted by name.
- For each field of the class sorted by field name (except private static and private transient fields:
- The name of the field.
- The modifiers of the field written as a 32-bit integer.
- The descriptor of the field.
if a class initializer exists, write out the following:
The name of the method, .
The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
The descriptor of the method, ()V.
For each non-private constructor sorted by method name and signature:
The name of the method, .
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
For each non-private method sorted by method name and signature:
The name of the method.
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
So, to answer your question,
Would a removal of a public/private property cause a problem? Adding new properties, perhaps? Would a adding a new function to the class create problems? How about more constructors?
Yes, all these additions/removal by default will cause the problem.
But one way to overcome this is to explicitly define the SerialVersionUID, this will tell the serialization system that i know the class will evolve (or evolved) over the time and don't throw an error. So the de-serialization system reads only those fields that are present in both the side and assigns the value. Newly added fields on the de-serialization side will get the default values. If some fields are deleted on the de-serialization side, the algorithm just reads and skips.
Following is the way one can declare the SerialVersionUID,
private static final long serialVersionUID = 3487495895819393L;
来源:https://stackoverflow.com/questions/30795262/redis-serialization-and-deserialization