Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete field from old java class implementing Serializable

Suppose i have version of class MyClass where i have two fields int count and String name. And i have persisted the byte stream to file. After i delete the attribute name from the class then also the persisted byte stream is getting converted to object with no issues.

But as per the Serializable docs adding new attribute is compatible change but deleting attribute is incompatible change w.r.t. Serilaization. I am confused can somebody please help me understanding this. Thanks!!!!

like image 284
Trying Avatar asked Apr 28 '13 09:04

Trying


People also ask

What happens if a class implements serializable?

If a super class implements Serializable, then its sub classes do automatically. When an instance of a serializable class is deserialized, the constructor doesn't run. If a super class doesn't implement Serializable, then when a subclass object is deserialized, the super class constructor will run.

How do you prevent a variable from being serialized in a serializable class?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

How do you not allow serialization of attributes of a class in Java?

In order to prevent subclass from serialization we need to implement writeObject() and readObject() methods which are executed by JVM during serialization and deserialization also NotSerializableException is made to be thrown from these methods.

How can we prevent a field from serialization in Java?

If there are fields in Java objects that do not wish to be serialized, we can use the @JsonIgnore annotation in the Jackson library. The @JsonIgnore can be used at the field level, for ignoring fields during the serialization and deserialization.


2 Answers

A few points:

When an object is deserialized, any fields not found in the byte-stream will be initialized to null. Therefore, when you add a new field, when a new version object is deserialized from an old version byte-stream, the new field will be initialized to null. If null is considered to be an invalid value, you can provide a readObject method to handle conversion. Old versions can still be deserialized from the new byte-stream- the new field is just ignored.

If a field is deleted, the situation is reversed: the old version class will now be missing a field. The missing field will be set to null. However, unlike the previous case, the old version can't add a readObject method (if you could add that method, then it would become the latest new version). Hence, deleting a field is considered to be incompatible.

In summary, the ability to create a readObject method in the new version class allows it to cope with the old version byte-stream when a new field is added. Unfortunately, the reverse is not possible.

It is important to note that, unless specifically defined, the serialVersionUID field will be automatically generated and will most likely change with practically all notable changes to a class. If two class versions have different serialVersionUID, an exception will be thrown when trying to carry out serialization/deserialization on a older or newer version byte-stream. If you don't manually set serialVersionUID, then no versions of your class will be compatible in terms of serialization.

P.S. If null happens to be a valid state for the deleted field (in the old version), then I guess you will be okay to delete fields. However, that is probably an edge case.

like image 156
Kevin Avatar answered Nov 07 '22 22:11

Kevin


Provided the serialVersionUID remains the same, field addition and deletion are both compatible under the rules defined in the Object Versioning chapter of the Object Serialization Specifcation, which you should certainly read.

like image 32
user207421 Avatar answered Nov 07 '22 23:11

user207421