处理不再存在的枚举值的反序列化

时间:2012-01-05 13:53:05

标签: java serialization enums

我有一个包含3个值的枚举JJJ:A,B和C.在我的程序的先前版本中,它有一个额外的值:D。我希望能够读入创建的序列化对象通过以前版本的程序,但遇到带有值的JJJ类型变量时会抛出异常' D'在序列化对象中。最理想的是,我希望能够拦截反序列化过程,并告诉它只要遇到它们就将D映射到C&C。

根据http://docs.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch.html(Enum Constants的序列化),听起来没有一种简单的方法可以做到这一点......我知道一种方法是覆盖类上的readObject包含JJJ类型的成员变量,但由于程序的大小和范围,这将是困难和痛苦的(许多可序列化的类具有JJJ类型的成员变量并且重写readObject来处理JJJ字段意味着我必须手动处理所有其他字段。)

我也尝试通过滚动我自己的ObjectInputStream子类来解决这个问题,但遗憾的是我真正需要的枚举反序列化位和覆盖来解决这个问题都是私有或包私有...

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

我实际上没有尝试过这个,但也许它可以工作:

  1. 创建一个新类“oldClass”,其字段与旧字段完全相同。

  2. this post describes的方式扩展ObjectInputStream,以便在“oldClass”的实例中反序列化。

  3. 在您创建的“oldClass”中,实现“readResolve()”,以便返回类的新版本的实例,根据需要更改缺少的字段。

答案 1 :(得分:0)

仅供参考,对于那些试图处理此案例的其他可怜人来说,这是我最终实施的解决方案:

我为枚举创建了一个特殊界面,如下所示:

public interface SerialCompatEnum {
    public String convertOldValue(String oldValue);
}

然后我编写了一个类,它将原始的序列化java对象字节流作为输入,处理它,并将字节流的修改版本写入任意输出流。处理逻辑选取序列化字节流中的任何枚举实例,并使用convertOldValue方法将流中的枚举常量替换为实际存在于当前代码库中的更新字符串。我们首先通过此处理器运行所有序列化对象,以防止由于缺少枚举常量而导致的完全失败。

不幸的是,这不是一个非常干净或简单的解决方案。 :/