Introduction:
Serialization: The process of writing state of an object to a file is called serialization but strictly speaking it is the process of converting an object form or java supported form into a file supported form or network supported form.
By using FileOutputStream and ObjectOutputStream classes we can implement serialization.
Deserialization: The process of reading state of an object from the file is called deserialization but strictly speaking it is the process of converting an object from either file supported form or network supported form into java supported form.
By using FileInputStream and ObjectInputStream classes we can implement deserialization.
Output:
i is 10 and j is 20
- we can serialize only Serializable objects.
- An Object is to be serializable if and only if the corresponding class implements Serializable interface.
- Serializable interface present in java.io package and it does not contain any methods. It is marker interface.
- If we are trying to serialize a non-serializable object then we will get runtime exception saying NotSerializableException.
transient keyword:
- transient modifier applicable only for variables but not for methods and classes.
- At the time of serialization if we don’t want to save the value of particular variable to meet security constraints then we should declare that variable as transient.
- while performing serialization JVM ignores the original value of transient variable and save default value to the file.
- Hence transient means not to serialize.
transient versus static:
static variable is not part of object state and hence it won’t participate in serialization. Due to this declaring static variable as transient, there is no use.
final versus transient:
final variables will be participated in the serialization directly by the value. Hence declaring a final variable as transient there is no impact.
Declaration | Output |
---|---|
int i = 10; int j = 20; |
i is 10 and j = 20 |
transient int i = 10; int j = 20; |
i is 0 and j = 20 |
transient static int i = 10; transient int j = 20; |
i is 10 and j = 0 |
transient int i = 10; transient final int j = 20; |
i is 0 and j = 20 |
transient static int i = 10; transient final int j = 20; |
i is 10 and j = 20 |
Note:We can serialize any no of objects to the file but which order we are serialized in the same order only we have to deserialized i.e., order of objects is important in serialization.
For Example:
If we don’t know the order of objects in serialization??
Object Graphs in serialization:
Whenever we are serializing an object then the set of all objects which are reachable from that object will be serialized automatically. this group of objects is nothing but object graph.
in object graph every object should be serializable. if at least one object is not serializable then we will get runtime exception saying NotSerializableException.
Output:
j is 20
In the above program whenever e=we are serializing Dog object automatically Cat and rat objects got serialized because these are part of object Graph of Dog.
Among Dog, Cat and Rat Objects if at least one object is not serializable then we will get runtime exception saying NotSerializableException.
Customized serialization:
During default serialization they may be chance of loss of information because of transient keyword.
Output:
Username is kalyan and password is pwd@1234
Username is kalyan and password is null
In the above example before serialization Account object can provide proper username and password but after deserialization Account object can provide only username but not password. This is due to declaring password variable as transient. hence during keep on serialization there may be a chance loss of information because of transient keyword.
To recover this loss of information we should go for customized serialization.
we can implement customized serialization by using the following two methods.
This method will be executed automatically at the time of serialization.
Hence at the time of serialization if we want to perform any activity we have to define that in this method only.
This method will be executed automatically at the time of deserialization.
Hence at the time of deserialization if we want to perform any activity, we have to define that in this method only.
Note: The above methods are callback methods because these are executed automatically by the JVM.
While performing which object serialization we have to do extra work in the corresponding class we have to define above methods.
For example, while performing Account object serialization if we require to do extra work, in that Account class we have to define above methods
Output:
Username is kalyan and password is pwd@1234
Username is kalyan and password is pwd@1234
In the above program before serialization and after serialization Account object can provide proper username and password.
Note: programmer can’t call private methods directly from outside of the class. JVM can call private methods directly from outside of the class.
Output:
Username is kalyan and password is pwd@1234 and pin is 1234
Username is kalyan and password is pwd@1234 and pin is 1234
serialization w.r.to inheritance:
case: 1
Even though child class doesn’t implement Serializable we can serialize child class object if parent class implements Serializable interface. i.e., serializable nature is inheriting from parent to child.
hence if parent is Serializable then every child is serializable.
In the above example even though Dog class doesn’t implement Serializable we can serialize Dog object because its parent Animal class implements Serializable.
Note: Object class doesn’t implement serializable interface.
Case: 2
Even though parent class doesn’t implement serializable we can serialize child class object if child class implements serializable interface i.e., to serialize child class object parent class need not be serializable.
At the time of serialization JVM will check is any variable inheriting from non-serializable parent or not . if any variable inheriting from non-serializable parent, then JVM ignores original value and save default value to the file.
At the time of deserialization JVM will check is any parent class is non serializable or not. if any parent class is non serializable then JVM will execute instance control flow in every non serializable parent and share its instance variable to the current object.
while executing instance control flow of non-serialize parent JVM will always call no-args constructor. hence every non serializable class should compulsorily contain no-args constructor. It may be default constructor generated by compiler or customised constructor explicitly provided by programmer.
Otherwise, we will get runtime exception saying InvalidClassException.
For Example InvalidClassException [args constructor]
Output:
InvalidClassException
Externalization:
In serialization everything takes care by JVM and programmer doesn’t have any control.
In serialization it is always possible to save total object to the file and it is not possible to save part of the object, which may create performance problems.
To overcome this problem, we should go for externalization.
The main advantage of externalization over serialization is everything takes care by programmer and JVM doesn’t have any control.
Based on our requirement we can either save total object or part of the object which improves performance of the system.
To provide Externalizable ability for any java object compulsory the corresponding class should implement Externalizable interface.
Externalizable interface defines two methods.
Externalizable is the child interface of Serializable
Serializable(I) (1.1 Version)
Externalizable(I) (1.1 Version)
This method will be executed automatically at the time of serialization.
Within this method we have to write code to save required variables to the file.
This method will be executed automatically at the time of deserialization.
Within this method we have to write code to read required variables from the file and assign to current object.
For strictly speaking at the time of deserialization JVM will create a separate new object by executing public no-args constructor.
On that object JVM will call readExternal() method.
Hence every Externalizable implemented class should compulsorily contain public no-args constructor otherwise we will get runtime exception saying InvalidClassException.
If the class implements Serializable then total object will be saved to the file.
In this case output is
Kalyan 10 20
If the class implements Externalizable then only required variables will be saved to the file.
In this case output is
public no-args constructor
kalyan 10 0
Note: In serialization transient keyword will play role but in externalization transient keyword wont play any role of course transient keyword not required in externalization.
Differences between Serialization and Externalization:
Serialization | Externalization |
---|---|
It is meant for Customized Serialization | It is meant for Customized Serialization |
Here everything takes care by JVM and programmer doesn’t have any control | Here everything takes care by programmer and JVM doesn’t have any control |
In this case it is always possible to save total object to the file and it is not possible to save part of the object | Based on our requirement we can save either total object or part of the object |
It is the best choice if we want to save total object of the file | It is the best choice if we want to save part of the object of the file |
Serializable interface doesn’t contain any methods and it is marker interface | Externalizable interface contains two methods writeExternal() and readExtrenal() and hence it is marker interface |
Serializable implemented class not required to contain public no-args constructor | Externalizable implemented class should compulsory contain public no-args constructor. Otherwise, we will get runtime exception saying InvalidClassException. |
transient keyword will play role in serialization | transient keyword won’t play role in externalization, of course it won’t be required. |
serialVersionUID:
In serialization both sender and receiver need not be same person, need not use same machine and need not be from same location.
The persons may be different, the machines may be different and locations may be different.
In serialization both sender and receiver should have .class file at beginning only just state of object is travelling from sender to receiver.
At the time of serialization with every object sender side JVM will save a unique identifier.
JVM is responsible to generate this unique identifier based on .class file.
At the time of deserialization receiver side JVM will compare unique identifier associate with object with local class unique identifier. If both are matched then only deserialization will be performed otherwise, we will get runtime exception saying InvalidClassException
This unique identifier is nothing but serialVersionUID.
Problems of depending on default serialVersionUID generated by JVM:
1. Both sender and receiver should use same JVM with respect to vendor and platform and version Otherwise receiver unable to deserialize because of different serialVersionUIDs.
2. Both sender and receiver should use same .class file version. After serialization if there is any change in .class file at receiver side then receiver unable to deserialize.
3. To generate serialVersionUID internally JVM may use complex algorithm which may create performance problems.
4. we can solve above problems by configuring our own serialVersionUID.
we can configure our own serialVersionUID as follows
Output:
i is 10 and j is 20
In the above program after serialization if we perform any change to the .class file a receiver side we won’t get any problem at the time of deserialization.
In this case sender and receiver not required to maintain same JVM versions.
Note:
some IDEs prompt programmer to enter serialVersionUID explicitly.
Some IDEs may generate serialVersionUID automatically.
0 Comments