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!!!!
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With