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?
推荐答案
反序列化问题的原因是什么?
在回答您的问题之前,我想给您介绍一下背景,
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.
方法的描述符.
所以,回答你的问题,
移除公共/私有财产会导致问题吗?添加新属性,也许?向类中添加新函数会产生问题吗?更多的构造函数怎么样?
是的,所有这些默认添加/删除都会导致问题.
但是克服这个问题的一种方法是显式定义 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屋!