Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
}
like image 785
Joe Kearney Avatar asked Mar 26 '26 19:03

Joe Kearney


1 Answers

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.

like image 163
JB Nizet Avatar answered Mar 28 '26 08:03

JB Nizet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!