Thierry Roy
Thierry Roy

Reputation: 8512

Maintaining a Serializable class in Java/Android

I'm serializing an object to a blob in a SQLiteOpenHelper like so:

final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(value);
out.close();

Each class define its own serialVersionUID that never change.

How does the serialization/deserialization actually work? Does it remember the name of the field, and the value associated with it? If I keep adding/removing field, is there a chance that an existing field have their value modified?

For example, let's say I serialize this class:

public class Foo implements Serializable {
     private static final long serialVersionUID = 4068188167994381987L;
     String x;
     int y;
}

Where x is "A", and y is 1;

Then I modify the class like so:

public class Foo implements Serializable {
     private static final long serialVersionUID = 4068188167994381987L;
     float f;
     String x;
}

If I keep adding/removing field, will each time that I deserialize Foo x still be "A"?

Upvotes: 1

Views: 2322

Answers (3)

Olivier Croisier
Olivier Croisier

Reputation: 6149

I would use the "magic" serialization methods writeObject and readObject to define a custom serialization stream. That way, the new version of your class could read the old format, and populate the new fields based on some conversion algorithm (here, read the y int and set f's value based on it).

For more information on serialization "magic" methods, see here : http://thecodersbreakfast.net/index.php?post/2011/05/12/Serialization-and-magic-methods

Upvotes: 0

Ashwinee K Jha
Ashwinee K Jha

Reputation: 9317

No, if you change order of fields or type of fields the deserialization will not work correctly. It will either lead to exception or read incorrect data.

Thats why it is recommended to change the serialVersionUID everytime you make change so that serialized format of class has changed.

If you want flexiblity of changing the class internals without breaking the serialization you should use Externalizable interface.

Upvotes: 1

thaussma
thaussma

Reputation: 9886

You cannot delete a field. See here at Oracle for compatible changes to your Serializable class.

Yes after the change in class Foo a deserialization of a older Foo would set x to 'A', but because you removed a field this does not work.

I suggest keeping the old field y and marking it @deprecated:

public class Foo implements Serializable {
    private static final long serialVersionUID = 4068188167994381987L;
    String x;
    float f;
    @deprecated int y;
}

Upvotes: 3

Related Questions