Externalization
In this tutorial, we are going to discuss about Externalization in java. Externalization in Java provides an alternative approach to serialization where the class itself controls the serialization and deserialization process. Unlike standard serialization, which automatically serializes and deserializes the entire object state, externalization allows the class to define custom methods for writing and reading object data.
- In default serialization every thing takes care by JVM and programmer doesn’t have any control.
- In serialization total object will be saved always and it is not possible to save part of the object, which creates performance problems at certain point.
- To overcome these problems we should go for externalization where every thing takes care by programmer and JVM doesn’t have any control.
- The main advantage of externalization over serialization is we can save either total object or part of the object based on our requirement.
- To provide Externalizable ability for any object compulsory the corresponding class should implements externalizable interface.
- Externalizable interface is child interface of serializable interface.
Externalizable interface defines 2 methods
1. writeExternal( )
2. readExternal( )
public void writeExternal(ObjectOutput out) throws IOException
This method will be executed automatically at the time of Serialization with in this method, we have to write code to save required variables to the file.
public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException
This method will be executed automatically at the time of deserialization with in this method, we have to write code to save read required variable from file and assign to the current object
At the time of deserialization JVM will create a separate new object by executing public no-arg constructor on that object JVM will call readExternal() method.
Every Externalizable class should compulsory contains public no-arg constructor otherwise we will get RuntimeExcepion saying “InvaidClassException”.
package com.ashok.files;
import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
/**
*
* @author ashok.mariyala
*
*/
class MyExternal implements Externalizable {
String s;
int i;
int j;
public MyExternal() {
System.out.println("Inside Constructor");
}
public MyExternal(String s, int i, int j) {
this.s = s;
this.i = i;
this.j = j;
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(s);
out.writeInt(i);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
s = (String) in.readObject();
i = in.readInt();
}
}
public class MyExternalizable {
public static void main(String[] args) throws Exception {
MyExternal external = new MyExternal("Waytoeasylearn", 10, 20);
FileOutputStream fos = new FileOutputStream("ashok.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(external);
FileInputStream fis = new FileInputStream("ashok.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
MyExternal t2 = (MyExternal) ois.readObject();
System.out.println(t2.s + ", " + t2.i + ", " + t2.j);
}
}
Output
Inside Constructor
Waytoeasylearn, 10, 0
1. If the class implements Externalizable interface then only part of the object will be saved in the case output is
Inside Constructor
Waytoeasylearn, 10, 0
2. If the class implements Serializable interface then the output is
Waytoeasylearn, 10, 20
3. In externalization transient keyword won’t play any role, hence transient keyword not required.
Difference between Serialization & Externalization
serialVersionUID
- To perform Serialization & Deserialization internally JVM will use a unique identifier, which is nothing but serialVersionUID .
- At the time of serialization JVM will save serialVersionUID with object.
- At the time of Deserialization JVM will compare serialVersionUID and if it is matched then only object will be Deserialized otherwise we will get RuntimeException saying “InvalidClassException”.
The process in depending on default serialVersionUID are
- After Serializing object if we change the .class file then we can’t perform deserialization because of mismatch in serialVersionUID of local class and serialized object in this case at the time of Deserialization we will get RuntimeException saying in “InvalidClassException”.
- Both sender and receiver should use the same version of JVM if there any incompatibility in JVM versions then receive unable to deserializable because of different serialVersionUID, in this case receiver will get RuntimeException saying “InvalidClassException” .
- To generate serialVersionUID internally JVM will use complex Algorithm which may create performance problems.
We can solve above problems by configuring our own serialVersionUID. We can configure serialVersionUID as follows
private static final long serialVersionUID = 1L;
class Dog implements Serializable {
private static final long serialVersionUID=1L;
int i=10;
int j=20;
}
class Sender {
public static void main(String[] args) throws Exception {
Dog d1=new Dog();
FileOutputStream fos=new FileOutputStream("abc.ser");
ObjectOutputStream oos= new ObjectOutputStream(fos);
oos.writeObject(d1);
}
}
class Receiver {
public static void main(String[] args)throws Exception {
FileInputStream fis=new FileInputStream("abc.ser");
ObjectInputStream ois=new ObjectInputStream(fis);
Dog d2=(Dog) ois.readObject();
System.out.println(d2.i+"-----"+d2.j);
}
}
In the above program after serialization even though if we perform any change to Dog.class file, we can de-serialize object. We if configure our own serialVersionUID both sender and receiver not required to maintain the same JVM versions.
Note
Some IDE’s generate explicit serialVersionUID.