The Externalizable interface provides the facility of custom serialization by writing the state of an object into a byte stream by making some changes or compress format.
Pre-requisite:
The Externalizable interface is not a marker interface. It extends Serializable interface and provides two methods for serialization and deserialization of object:
Serialization
public void writeExternal(ObjectOutput out) throws IOException
Deserialization
public void readExternal(ObjectInput in) throws IOException
Advantage of Externalizable
- Externalizable is fast in comparison to default serialization. Because JVM uses reflection when you use serializable which is quite slow.
- Externalizable performance is fast because don’t store unnecessary information. While default serialization store information about class description i.e class description, its superclass, and instance variable associated with that class.
Disadvantage of Externalizable
- Once any change happens on the class definition, we have to also change our implementation on writeExternal() and readExternal() accordingly.
- In the case of inheritance, the Subclass object has to coordinate with its superclass to save and store its state by calling super.xxxx() method from subclass.
See Also:
- Java: transient Serialization
- Java: static Serialization
- Java: Object Serialization with Inheritance
- Java: Object Externalizable Serialization with Inheritance
- Java: Array and Collection Serialization
- Java: Serialization Exception Handling
Externalizable Example: Serialization and Deserialization
In this example, Employee class override writeExternal() and readExternal() method for serialization and deserialization of data. Here we have written our own statement to what data need to serialize. Here you can also consider this example of data compression as storing data as compressed because not storing irrelevant data.
import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; public class Employee implements Externalizable { int id; String name; transient int age; public Employee() { } public Employee(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } @Override public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException { String []str=oi.readUTF().split("[|]"); this.id=Integer.parseInt(str[0]); this.name=str[1]; this.age=Integer.parseInt(str[2]); } @Override public void writeExternal(ObjectOutput oo) throws IOException { oo.writeUTF(this.id+"|"+this.name+"|"+this.age); } }
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class ExternalizableCompressionExample { public static void main(String[] args) throws Exception { // creating employee object Employee e1 = new Employee(111, "Saurabh", 35); serializeEmployee(e1, "employee.txt"); e1 = deserializeEmployee("employee.txt"); System.out.println("Employee Detail :"); System.out.println("Id :" + e1.id + "\nName: " + e1.name + "\nAge: " + e1.age); } private static void serializeEmployee(Employee e1, String fileName) throws Exception { // writing object into employee file FileOutputStream f = new FileOutputStream(fileName); ObjectOutputStream out = new ObjectOutputStream(f); // Serialize employee object as stream and write in file out.writeObject(e1); out.flush(); out.close(); f.close(); System.out.println("Employee object Serialize Successfully"); } private static Employee deserializeEmployee(String fileName) throws Exception { // Read object stream from file ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName)); //Deserialize object stream to employee object Employee e = (Employee) in.readObject(); in.close(); return e; } }
Output
Employee Detail :
Id :111
Name: Saurabh
Age: 35