-
Notifications
You must be signed in to change notification settings - Fork 3
Serialization
A lot of people think that serialization is quite simple - all that we do is implement java.io.Serializable
interface.
Yes, in simple - it's all that we need, but what about different finer points? How many ways are there to serialize object? One? Two? The right answer is - two ways! We can:
- implements
java.io.Serializable
- implements
Externalizable
Let's talk about it more detail!
Standart serialization in Java works through Reflection API, class puzzles out for the fields and writes to the output. And ofcourse if we use reflection - it's not optimal. And another one - when we use standart serialization we don't call constructor of the class in deserialization, we reserve memory for the class and after that all class fields fill by values from stream(input). We don't call constructor!
And what about parent class? If our class is serializable, what about parent class? Parent class isn't serializable! When we deserialize our class - we call constructor without parameters! And we don't call constructor of class which we try to deserialize. If we haven't got this constructor - we catch an error. After our example in code - we have class with parameter i which we recieve after deserialization and other parameters create default constructor.
Another approach!
Instead of java.io.Serializable
this interface contains two methods – writeExternal(ObjectOutput)
and readExternal(ObjectInput)
. All logic of serialization and deserialization is here.
How it works?
First of all we call default constructor. And that is why we MUST have public default constructor. All children should have it too.
After that on new object of our class we call methods(readExternal) and all our fields are filling data.
If field is transient
- it should have default value.
And thats important to say:
-
Static
fields doesn't serialize in standart approach, but in theory we can(don't do it!) serialize it by Externalizable. - We can't deserialize
final
fields of class - cause we use consrtuctor.
Why we have private static final long serialVersionUID? This field contains unique id version of serizalization class. It calculates by fields, order of field declaring, methods and etc. And if we change class state - we change this id. And this field writes to the serialization stream, when we deserialize our object we compare ids and if anything is wrong - throw exception.