Joe Kearney
Joe Kearney

Reputation: 7537

maintain Java serialization compatibility when changing type of a single final field

I have this old convenience class for manipulating dates (yyyy-MM-dd). It abstracts away some ugliness of using java.util.Date and Calendar but I want to rewrite it in terms of JodaTime LocalDate. (I won't be changing the interface, just implementation for now.)

The old version used default serialization, and had only the one int field.

How can I replace the final int field with a final LocalDate but retain serialization compatibility?

I can implement writeObject to write out the compatible int value instead of the LocalDate. But I don't believe readObject or readResolve allow me to read the int from the stream and write the LocalDate, without resorting to reflection.

Is there anything like a static readInstantiate method? Or a clever way of doing this with serialization proxies, still maintaining compatibility?


The current code:

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
}

Upvotes: 3

Views: 553

Answers (1)

JB Nizet
JB Nizet

Reputation: 692081

You're probably looking for the readResolve() method:

For Serializable and Externalizable classes, the readResolve method allows a class to replace/resolve the object read from the stream before it is returned to the caller. By implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized. The method is defined as follows:

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

So, you need to make the LocalDate field transient, and to use the readResolve class to read transform the read serialized object, containing only the int field, to a new instance containing a LocalDate created from the int value.

Upvotes: 2

Related Questions