Java-修改二进制序列化对象的SerialVersionId

Java-修改二进制序列化对象的SerialVersionId,java,serialization,serialversionuid,Java,Serialization,Serialversionuid,几个月前,我将一个java.io.Serializable对象序列化到一个文件中。现在我需要阅读内容,但从那时起serialVersionUID已经更改,现在我得到了一个“类不兼容”错误。我知道一个事实,即没有任何数据成员已更改,因此唯一的障碍是serialVersionUID检查 有没有办法禁用检查或修改二进制文件中的serialVersionUID 澄清 这个问题假设我无法编辑源代码。有没有一种方法可以破解.class文件,或者破解序列化的对象文件(使用十六进制编辑器并更改某个偏移量处的值)

几个月前,我将一个java.io.Serializable对象序列化到一个文件中。现在我需要阅读内容,但从那时起serialVersionUID已经更改,现在我得到了一个“类不兼容”错误。我知道一个事实,即没有任何数据成员已更改,因此唯一的障碍是serialVersionUID检查

有没有办法禁用检查或修改二进制文件中的serialVersionUID

澄清


这个问题假设我无法编辑源代码。有没有一种方法可以破解.class文件,或者破解序列化的对象文件(使用十六进制编辑器并更改某个偏移量处的值)?

有文件记载,序列化不用于持久化数据。为了恢复该数据,您需要将JVM的版本降级为用于输出该数据的版本


作为将来的参考,不要使用序列化在JVM会话之间持久化数据。

为什么不按照文档中的描述修改当前版本中的serialVersionUID?

作为一种黑客,您可以使用serialVer工具生成JVM可能正在使用的serialVer:

serialver-类路径com.foo.bar.MyClass


如果您随后在类中手动设置serialVerUID,那么它应该匹配并且应该能够加载,假设您没有以使类无效的方式更改该类

我最近发现自己处于一种类似的情况——我必须读取一些序列化对象,这些对象的
serialVersionUID
与最新版本不同,在我的例子中,在同一个类的文件中存储了两个不同的
serialVersionUID
s(显然存储在不同的时间). 因此,我没有机会修改类并设置其
serialVersionUID
;实际上,我必须进去修改存储的数据

我(通过阅读java.io源代码)得出的结论是,首先存储类名(使用
writeUTF()
),然后立即使用
writeLong()
保存
serialVersionUID
,对象就会被序列化


我的解决方案是捕获异常,然后返回,查找类名,并在类名之后立即用新的替换旧的
serialVersionUID

他的问题的编写方式表明该对象不在他的控制之下,无法进行更改。但如果是这样,则是的。将serialVersionUID更改回写入数据时的状态将允许他重新读取数据。如果该类不在他的控制下,这并不重要。他可以用相同的名称、成员和SerialVersionUID编写一个新的类。只有当类没有从旧版本反序列化时中断的元素时,这才有效。如果您删除一个成员变量并试图用serialVersionUID愚弄它,它将从旧文件中抛出一个反序列化异常。@SteveB:请阅读以下问题:“我知道事实上没有任何数据成员已更改,因此唯一的障碍是serialVersionUID检查。”要使其起作用,您需要像序列化对象时一样访问类文件。希望它在版本控制存档中?您也可以编写自己的readObject,我认为您可能能够按照声明的顺序读取字段。只要设置serialVersionUID,您就可以以这种方式使用序列化。根据Serializable文档-“因此,为了保证不同java编译器实现之间的SerialVersionId值一致,可序列化类必须声明一个显式的SerialVersionId值。”考虑到更新类时无法访问和获取数据,这可能是真的。您需要做的是使用未更新版本的类加载数据,并将其传递给新类,然后再次序列化(在运行时),这在大多数情况下是不可行的。