2

想象一下,我有一个Foo过去有serialVersionUIDs 1、3 和 17 的类,我需要能够将所有三个版本读入Foo实例。我怎么做?

我特别需要知道字节流中保存的是哪个版本,所以我可以做一些数据迁移。如何访问serialVersionUIDin readObject()?还是已经太晚了?

4

3 回答 3

2

这并不容易,但可能。对于每个历史版本的类,您需要创建单独的类加载器,它将加载旧版本的数据模型类。然后,您需要尝试使用每个类加载器读取您的文件,直到其中一些适合。我相信ObjectInputStream使用来自线程上下文的当前类加载器。如果您需要更多详细信息,请随时问我。

后期补充:好像指定哪个类加载器会被ObjectInputStream. 这里可能需要进一步调查。

另一个后来的补充:可能你可以覆盖resolveClass(ObjectStreamClass)方法ObjectInputStream来制作是使用正确的类加载器。

于 2013-02-06T13:36:36.933 回答
2

使用不同的类加载器来反序列化对象的不同版本。之后,您必须根据以前的版本手动初始化通用(可能是最新的)实例的内部状态(您必须为此编写转换器)。

确保您的类加载器路径是完全不同的。如果一个超级类加载器可以加载一个类,它就会加载。所以,所有的类加载器应该是完全独立的(都不应该是其他类的超类)。

于 2013-02-06T13:37:14.603 回答
1

您可以通过在反序列化期间捕获错误来获得前者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
}
于 2013-02-06T13:58:25.503 回答