想象一下,我有一个Foo
过去有serialVersionUID
s 1、3 和 17 的类,我需要能够将所有三个版本读入Foo
实例。我怎么做?
我特别需要知道字节流中保存的是哪个版本,所以我可以做一些数据迁移。如何访问serialVersionUID
in readObject()
?还是已经太晚了?
想象一下,我有一个Foo
过去有serialVersionUID
s 1、3 和 17 的类,我需要能够将所有三个版本读入Foo
实例。我怎么做?
我特别需要知道字节流中保存的是哪个版本,所以我可以做一些数据迁移。如何访问serialVersionUID
in readObject()
?还是已经太晚了?
这并不容易,但可能。对于每个历史版本的类,您需要创建单独的类加载器,它将加载旧版本的数据模型类。然后,您需要尝试使用每个类加载器读取您的文件,直到其中一些适合。我相信ObjectInputStream
使用来自线程上下文的当前类加载器。如果您需要更多详细信息,请随时问我。
后期补充:好像指定哪个类加载器会被ObjectInputStream
. 这里可能需要进一步调查。
另一个后来的补充:可能你可以覆盖resolveClass(ObjectStreamClass)
方法ObjectInputStream
来制作是使用正确的类加载器。
使用不同的类加载器来反序列化对象的不同版本。之后,您必须根据以前的版本手动初始化通用(可能是最新的)实例的内部状态(您必须为此编写转换器)。
确保您的类加载器路径是完全不同的。如果一个超级类加载器可以加载一个类,它就会加载。所以,所有的类加载器应该是完全独立的(都不应该是其他类的超类)。
您可以通过在反序列化期间捕获错误来获得前者serialVersionUID
:
try {
// deserialize here...
} catch (final java.io.InvalidClassException e) {
System.out.println(e.getMessage());
// The message string contains the former uid.
// Message: local class incompatible: stream classdesc serialVersionUID = OLD_UID_HERE, local class serialVersionUID = NEW_UID_HERE
}