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

我有一个包含3个值的枚举JJJ:A,B和C.在我的程序的先前版本中,它有一个额外的值:D。我希望能够读入由以前版本的创建的序列化对象程序,但遇到序列化对象中值为“D”的JJJ类型变量时抛出exception。 最理想的情况是,我希望能够拦截反序列化过程并告诉它在遇到它们时将D’映射到C’。

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

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

有什么建议么?

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

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

  2. 按照本文描述的方式扩展ObjectInputStream,以便在“oldClass”的实例中反序列化。

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

仅供参考,对于那些试图处理这种情况的其他可怜的灵魂,这是我最终实施的解决方案:

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

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

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

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