Say I have an ArrayList<B> array of objects from a certain class B, which extends A. B has an instance field bb and A a field aa. I know that saving array to a .dat-file using ObjectOutputStream requires that B (not just ArrayList!) implement Serializable. I’ve found, however, that when loading the object back from the file (using an ObjectInputStream):
arrayLoaded = (ArrayList<B>)myObjIn.readObject();
the loaded array isn’t identical to the original array: In the particular case, arrayLoaded.get(0).bb has the same value as in array, but arrayLoaded.get(0).aa is “zeroed”. It has a default initialization value, regardless of its value when array was saved to file. However, this problem is solved by letting also A implement Serializable.
What bothers me is that this error is so subtle: no exception, no warning (in eclipse), nothing. Is there a reason for this or is this simply an oversight by the java developers? Do I just have to accept it and think hard about which classes in the hierarchy implement Serializable every time I want to use object IO streams?
Just because
BimplementsSerializable, that does not retroactively include the fields of the non-serializable superclass in what gets serialized. (This makes sense, especially when you consider that being able to serialize private and package-private fields of any class just by extending it and implementingSerializablewould violate its encapsulation.)A field declared in
Awill behave the same as a field declared astransientinB. There is a workaround however. From the documentation forSerializable:So you will need to implement
writeObjectandreadObjectinBto handle the serialization/deserialization ofA.aa.