我注意到我存储在 Redis 中的一些序列化对象存在反序列化问题。
这通常发生在我对存储在 Redis 中的对象类进行更改时。
我想了解这个问题,以便我可以有一个清晰的解决方案设计。
我的问题是,是什么导致反序列化问题?移除公共/私有财产会导致问题吗?添加新属性,也许?向类中添加新功能会产生问题吗?更多的构造函数怎么样?
在我的序列化对象中,我有一个属性 Map,如果我更改(更新一些属性、添加功能等)myObject,会导致反序列化问题吗?
我注意到我存储在 Redis 中的一些序列化对象存在反序列化问题。
这通常发生在我对存储在 Redis 中的对象类进行更改时。
我想了解这个问题,以便我可以有一个清晰的解决方案设计。
我的问题是,是什么导致反序列化问题?移除公共/私有财产会导致问题吗?添加新属性,也许?向类中添加新功能会产生问题吗?更多的构造函数怎么样?
在我的序列化对象中,我有一个属性 Map,如果我更改(更新一些属性、添加功能等)myObject,会导致反序列化问题吗?
是什么导致反序列化问题?
在回答你的问题之前,我想给你一些背景知识,
序列化运行时将版本号与每个可序列化类相关联,称为 serialVersionUID,在反序列化期间使用该版本号来验证序列化对象的发送方和接收方是否已为该对象加载了与序列化兼容的类。如果接收者为对象加载了一个类,该对象的 serialVersionUID 与相应发送者的类不同,则反序列化将导致 InvalidClassException。
如果一个可序列化的类没有显式声明一个serialVersionUID,那么序列化运行时将根据类的各个方面为该类计算一个默认的serialVersionUID值,它使用类的以下信息来计算SerialVersionUID,
如果存在类初始值设定项,请写出以下内容:
方法的名称,。
方法的修饰符 java.lang.reflect.Modifier.STATIC,写成 32 位整数。
方法的描述符,()V。
对于按方法名称和签名排序的每个非私有构造函数:
方法的名称,。
方法的修饰符写为 32 位整数。
方法的描述符。
对于按方法名称和签名排序的每个非私有方法:
方法的名称。
方法的修饰符写为 32 位整数。
方法的描述符。
所以,回答你的问题,
移除公共/私有财产会导致问题吗?添加新属性,也许?向类中添加新功能会产生问题吗?更多的构造函数怎么样?
是的,默认情况下所有这些添加/删除都会导致问题。
但是解决这个问题的一种方法是显式定义 SerialVersionUID,这将告诉序列化系统我知道该类会随着时间的推移而演变(或演变)并且不会引发错误。所以反序列化系统只读取两边都存在的那些字段并赋值。反序列化端新添加的字段将获得默认值。如果在反序列化端删除了某些字段,算法只是读取并跳过。
以下是声明 SerialVersionUID 的方式,
private static final long serialVersionUID = 3487495895819393L;