Redis序列化和反序列化 [英] Redis Serialization and Deserialization
问题描述
我注意到存储在Redis中的某些序列化对象在反序列化方面遇到了问题。
I have noticed that some of my serialized objects stored in Redis have problems deserializing.
这通常是在我对存储在Redis中的对象类进行更改时发生的。
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?
在我的序列化对象中,我有一个属性Map,如果我更改(更新了某些属性,添加了功能等)myObject,会导致什么呢?反序列化问题?
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?
推荐答案
什么原因导致反序列化问题?
what causes deserialization problems?
在回答问题之前,我想给您一些背景知识,
I would like to give you bit of background before answering your question,
序列化运行时与每个可序列化的类相关联一个版本号,称为serialVersionUID,在反序列化期间用于验证序列化对象的发送者和接收者是否已加载了该对象的与序列化兼容的类。如果接收方已为该对象加载了一个与相应发送方类具有不同的serialVersionUID的类,则反序列化将导致InvalidClassException。
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.
如果是可序列化的类没有显式声明serialVersionUID,则序列化运行时将根据该类的各个方面为该类计算默认的serialVersionUID值,它使用该类的以下信息来计算SerialVersionUID,
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,
- 类名。
- 以32位整数形式编写的类修饰符。
- 每个接口的名称按名称排序。
- 对于按字段名称排序的类的每个字段(私有静态字段和私有瞬态字段除外:
- 字段名称。
- 以32位整数形式编写的字段修饰符。
- 字段描述符。
-
如果存在类初始值设定项,则写出以下内容:
- 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:
方法的名称。
方法的修饰符java.lang.reflect.Modifier STATIC,用32位整数表示。
The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
方法的描述符()V。
The descriptor of the method, ()V.
对于按方法名称和签名排序的每个非私有构造函数:
For each non-private constructor sorted by method name and signature:
该方法的修饰符写为32位整数。
The modifiers of the method written as a 32-bit integer.
方法。
对于按方法名称和签名排序的每个非私有方法:
For each non-private method sorted by method name and signature:
该方法的修饰符写为32位整数。
The modifiers of the method written as a 32-bit integer.
该方法的描述符。
所以,要回答您的问题,
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?
是的,默认情况下,所有这些添加/删除操作都会引起问题。
但是克服此问题的一种方法是显式定义SerialVersionUID,这将告诉序列化系统我知道该类将随着时间的推移而发展(或进化),而不必不要抛出错误。因此,反序列化系统仅读取双方都存在的那些字段并分配值。反序列化方面的新添加字段将获得默认值。如果在反序列化方面删除了某些字段,则该算法只会读取和跳过。
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.
以下是声明SerialVersionUID的方式,
Following is the way one can declare the SerialVersionUID,
private static final long serialVersionUID = 3487495895819393L;
这篇关于Redis序列化和反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!