在更改单个final字段的类型时保持Java序列化兼容性

时间:2013-07-24 16:24:48

标签: java serialization deserialization

我有一个旧的便利类来操作日期(yyyy-MM-dd)。它抽象了使用java.util.DateCalendar的一些丑陋,但我想用JodaTime LocalDate重写它。 (我不会改变界面,现在只是实现。)

旧版本使用默认序列化,只有一个int字段。

如何将final int字段替换为final LocalDate但保留序列化兼容性?

我可以实现writeObject来写出兼容的int值,而不是LocalDate。但我不相信readObjectreadResolve允许我从流中读取int并撰写LocalDate,而无需借助反思。

是否有类似静态readInstantiate方法的内容?或者使用序列化代理执行此操作的一种聪明方法,仍然保持兼容性?


当前代码:

public final class MyDay implements Serializable {
  private static final long serialVersionUID = 12345L;

  private final int isoDate;

  public MyDay(int isoDate) {
    this.isoDate = isoDate;
  }

  // lots of convenience methods for manipulating dates

  // no read/writeObject serialization methods in original
}

1 个答案:

答案 0 :(得分:2)

您可能正在寻找readResolve()方法:

  

对于Serializable和Externalizable类,readResolve方法允许类在返回到调用者之前替换/解析从流中读取的对象。通过实现readResolve方法,类可以直接控制被反序列化的自己的实例的类型和实例。该方法定义如下:

ANY-ACCESS-MODIFIER Object readResolve()
        throws ObjectStreamException;

因此,您需要使LocalDate字段成为瞬态,并使用readResolve类将读取的序列化对象(仅包含int字段)转换为包含从int值创建的LocalDate的新实例。