Serializable Vs Externalizable

Serialization
      It is the technique using which we can save the state of the Object into files,or we can transfer the object from 1 jvm to another jvm.

To Serialize the object,its class must implement Serializable interface.But Serializable interface  has some serious drawbacks1.Lets Assume the class Hierarchy
Object->A->B->C->D    (child class)
If you serialize the D class object,then all its superclass objects are also serialized(saved into file), which might be unnecessary sometimes.Not only the fields and properties are serialized,but also the class information,and their metadata is also serialized.

2.Assume Your class D has 100 fields/properties,out of which you are intrested to serialize only 5.
Are you going to declare all other 95 fields as transient to avoid serialization?This is another issue.
You really dont have any control on what you want to serialize and want you dont want to serialize.

3.You have serialized only 5 fields,but you are intrested to deserialize only 2.How do you do that?

You have no control on deserialization,which eats up unnecessary space.

4.When you implement Serializable interface,it is recommended to define int serialVersionUID, an unique Id to identify the information persisted. If you dont define the that,JVM automatically gives the serialVersionUID.JVM calculates this value by using all the fields and other information of all the classes in the hierarchy.In our example A,B,C,D and Object class.
Calculating that value is again a time consuming process.

5.When the Object is deserialized,the constructor is not called.So if you want to re-initialize few properties,you have to write the logic after constructing the object.
Otherwise we can write those initialization logic in some other method,and then override  the method  readObject(-) which internally calls readObject(-),so that our reinitializaiton logic will work.

Now comes the requirement:-

The requirement is very simple,we want to control Serialization.
Externalizable is the solution.
Externalizable is an interface which implements Serializable interface,but gives 2 methods

Features of Externalizable interface:-
1.It implements Serializable interface,but has given 2 methods
    public void writeExternal(ObjectOutput out) throws IOException
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException


2.It only serializes/writes the information about the current object,not the object of superclasses,as we have seen in Serializable interface.

3.Whatever you want to Serialize/deserialize you have to write the logic in writeExternal(-) and readExternal(-) method.So you have the entire control on Serialization.

4.The class that implements Externalizable interface,must have a 0-arg constructor
Steps to work with Externalizable interface
1.Your class must implement Externalizable interface,and should have 0-args constructor
   The 0-args constuctor would be needed while deserialization.

2.Implement 2 methods of Externalizable interface in your class
    public void writeExternal(ObjectOutput out) throws IOException
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException

3.define what you want to serialize inside writeExternal() and  what you want to deserialize in readExternal()

Lets Write the Program to Understand

Employee.java
import java.io.*;
class Employee implements Externalizable
{
    String ename;
    int age;
    double salary;

    public Employee()//0-arg constructor
    {
        System.out.println("Employee()");
    }
    //parameterized constructor
    public Employee(String name, int age, double salary) {
        System.out.println("Employee(-,-,-)");
        ename = name;
        this.age = age;
        this.salary = salary;
    }
    //Just prints everything
    public String toString()
    {
        return "Emp Name::"+ename+" Emp Age::"+age+" Emp Sal::"+salary;
    }

    //Here we have serialized only 2 properties,we have not serialized salary
    public void writeExternal(ObjectOutput out) throws IOException  {
        out.writeObject(ename);
        out.writeInt(age);
    }
    //Here we have mentioned what we want to deserialize,I am intrested to deserialize only ename
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        ename = (String) in.readObject();//it will be deserialized and stored in ename property
    }

}
ExternalizableDemo.java
public class ExternalizableDemo {
    public static void main(String args[])throws Exception {
        //parameterized constructor is called
        Employee emp=new Employee("Satya",23,15000.00);
        //Serialization process
        FileOutputStream fos = new FileOutputStream("d:/myFile.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(emp);
        oos.flush();
        oos.close();

        // Object deserialization
        FileInputStream fis = new FileInputStream("d:/myFile.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        //0-args constructor is called
        Employee emp2 = (Employee)ois.readObject();
        ois.close();
        System.out.println("Details ::: " + emp2);  //toString() is called,which prints the details
        //Note that only name is deserialized
    }
}
Note:-
To create Employee object,we are using parameterized constructor,
But to deserialize,JVM automatically looks for 0-args constructor.
Hope this article proves to be valuable one.

Comments

Popular posts from this blog

Theme display in javascript

How to know which liferay version we are using

Viewing the SQL Query in liferay : debugging the SQL Query in Hibernate