Monday, 22 September 2014

Externalization

Object Serialization uses the Serializable and Externalizable interfaces.In case of serialization, the serialization of the object is taken care automatically. Where as in externalization, it is the developr responsibility to what to serialize and what not to serialize.

How serialization happens?
As per javadoc, JVM first checks for the Externalizable interface and If the object supports Externalizable, the writeExternal method is called. If the object does not support Externalizable and does implement Serializable, the object is saved using ObjectOutputStream. When an Externalizable object is reconstructed, an instance is created using the public no-arg constructor, then the readExternal method called. Serializable objects are restored by reading them from an ObjectInputStream.

Externalizable interface provides two methods. The class which implements Externalizable interface, must provide the definition for these methods.

Method Description
readExternal(ObjectInput in) The object implements the readExternal method to restore its contents by calling the methods of DataInput for primitive types and readObject for objects, strings and arrays.
writeExternal(ObjectOutput out) The object implements the writeExternal method to save its contents by calling the methods of DataOutput for its primitive values or calling the writeObject method of ObjectOutput for objects, strings, and arrays.

import java.io.*;

public class Employee implements Externalizable{  
    int id;
    String firstName;
    String lastName;
    
    public Employee(){
        super();
    }
    
    Employee(int id, String firstName, String lastName){
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    @Override
    public void writeExternal(ObjectOutput out) throws IOException{
        out.writeObject(firstName);
        out.writeObject(lastName);
        out.writeInt(id);
    }
    
    @Override
    public void readExternal(ObjectInput in) throws ClassNotFoundException, IOException{
        firstName = (String)in.readObject();
        lastName = (String)in.readObject();
        id = (int)in.readInt();
    }
}

import java.io.*;

public class ExternalizeEx {
    public static void main(String args[]){
        Employee emp = new Employee(1, "Krishna","Arjun");
        Employee newEmp = null;
        
        /* Serialize Employee */
  try {
      FileOutputStream fout = new FileOutputStream("ser.out");
      ObjectOutputStream out = new ObjectOutputStream(fout);
      out.writeObject(emp);
            out.flush();
  } 
        catch (IOException e) {
      System.out.println(e);
      System.exit(1);
  }
        
        /* Deserialize Employee */
        try {
      FileInputStream fin = new FileInputStream("ser.out");
      ObjectInputStream in = new ObjectInputStream(fin);       
      newEmp = (Employee) in.readObject();
  }
  catch (IOException | ClassNotFoundException e) {
      System.out.println(e);
      System.exit(1);
  }
        
        System.out.println("Employee emp details");
        System.out.println(emp.id + " " + emp.firstName + " " + emp.lastName);
        
        System.out.println("New Employee newEmp details");
        System.out.println(newEmp.id + " " + newEmp.firstName +" " + newEmp.lastName);       
        
    }
}

Output
Employee emp details
1 Krishna Arjun
New Employee newEmp details
1 Krishna Arjun


In this example, class Employee implements Externalizable interface which means that Employee object is ready for serialization. Unlike serialization, you must specify what to serialize for Externalization. So when you write the "Employee" object to the OutputStream, the "writeExternal" method is called and the data is persisted. The same applies to "readExternal" method in the Employee object i.e., when you read the "Employee" object from the ObjectInputStream, "readExternal" method is called.

What if the super class of Employee doesn't implement Externalizable interface ?
Lets say there is a class 'EmployeeAddress' which is a super class of Employee, but it don't implement Externalizable interface. To persist the fields in the Employee class the writeExternal and readExternal methods of Employee class are modified to save/restore the super class fields first and then the sub class fields.

public class EmployeeAddress {
    String state, country;
    
    EmployeeAddress(String state, String country){
        this.state = state;
        this.country = country;
    }
    
    public EmployeeAddress(){
        super();
    }
}

import java.io.*;

public class Employee extends EmployeeAddress implements Externalizable{  
    int id;
    String firstName;
    String lastName;
    
    public Employee(){
        super();
    }
    
    Employee(int id, String firstName, String lastName, String st, String con){
        super(st, con);
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    @Override
    public void writeExternal(ObjectOutput out) throws IOException{
        out.writeObject(state);
        out.writeObject(country);
        out.writeObject(firstName);
        out.writeObject(lastName);
        out.writeInt(id);
    }
    
    @Override
    public void readExternal(ObjectInput in) throws ClassNotFoundException, IOException{
        state = (String)in.readObject();
        country = (String)in.readObject();
        firstName = (String)in.readObject();
        lastName = (String)in.readObject();
        id = (int)in.readInt();
    }
}

import java.io.*;

public class ExternalizeEx {
    public static void main(String args[]){
        Employee emp = new Employee(1, "Krishna","Arjun","AP", "India");
        Employee newEmp = null;
        
        /* Serialize Employee */
  try {
      FileOutputStream fout = new FileOutputStream("ser.out");
      ObjectOutputStream out = new ObjectOutputStream(fout);
      out.writeObject(emp);
            out.flush();
  } 
        catch (IOException e) {
      System.out.println(e);
      System.exit(1);
  }
        
        /* Deserialize Employee */
        try {
      FileInputStream fin = new FileInputStream("ser.out");
      ObjectInputStream in = new ObjectInputStream(fin);       
      newEmp = (Employee) in.readObject();
  }
  catch (IOException | ClassNotFoundException e) {
      System.out.println(e);
      System.exit(1);
  }
        
        System.out.println("Employee emp details");
        System.out.print(emp.id + " " + emp.firstName + " " + emp.lastName);
        System.out.println(emp.state +" " + emp.country);
        
        System.out.println("New Employee newEmp details");
        System.out.print(newEmp.id + " " + newEmp.firstName +" " + newEmp.lastName+" ");  
        System.out.println(newEmp.state +" " + newEmp.country);
        
    }
}

Output
Employee emp details
1 Krishna ArjunAP India
New Employee newEmp details
1 Krishna Arjun AP India

What if the super class of Employee also implement Externalizable interface ?
Since super class 'EmployeeAddress' implements Externalizable interface, we need to call the super class writeExternal and readExternal methods in sub class to maintain persistancy.

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class EmployeeAddress  implements Externalizable{
    String state, country;
    
    EmployeeAddress(String state, String country){
        this.state = state;
        this.country = country;
    }
    
    public EmployeeAddress(){
        super();
    }
    
     @Override
    public void writeExternal(ObjectOutput out) throws IOException{
        out.writeObject(state);
        out.writeObject(country);
    }
    
    @Override
    public void readExternal(ObjectInput in) throws ClassNotFoundException, IOException{
        state = (String)in.readObject();
        country = (String)in.readObject();
    }
}

import java.io.*;

public class Employee extends EmployeeAddress implements Externalizable{  
    int id;
    String firstName;
    String lastName;
    
    public Employee(){
        super();
    }
    
    Employee(int id, String firstName, String lastName, String st, String con){
        super(st, con);
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    @Override
    public void writeExternal(ObjectOutput out) throws IOException{
        super.writeExternal(out);
        out.writeObject(firstName);
        out.writeObject(lastName);
        out.writeInt(id);
    }
    
    @Override
    public void readExternal(ObjectInput in) throws ClassNotFoundException, IOException{
        super.readExternal(in);
        firstName = (String)in.readObject();
        lastName = (String)in.readObject();
        id = (int)in.readInt();
    }
}

import java.io.*;

public class ExternalizeEx {
    public static void main(String args[]){
        Employee emp = new Employee(1, "Krishna","Arjun","AP", "India");
        Employee newEmp = null;
        
        /* Serialize Employee */
  try {
      FileOutputStream fout = new FileOutputStream("ser.out");
      ObjectOutputStream out = new ObjectOutputStream(fout);
      out.writeObject(emp);
            out.flush();
  } 
        catch (IOException e) {
      System.out.println(e);
      System.exit(1);
  }
        
        /* Deserialize Employee */
        try {
      FileInputStream fin = new FileInputStream("ser.out");
      ObjectInputStream in = new ObjectInputStream(fin);       
      newEmp = (Employee) in.readObject();
  }
  catch (IOException | ClassNotFoundException e) {
      System.out.println(e);
      System.exit(1);
  }
        
        System.out.println("Employee emp details");
        System.out.print(emp.id + " " + emp.firstName + " " + emp.lastName +" ");
        System.out.println(emp.state +" " + emp.country);
        
        System.out.println("New Employee newEmp details");
        System.out.print(newEmp.id + " " + newEmp.firstName +" " + newEmp.lastName+" ");  
        System.out.println(newEmp.state +" " + newEmp.country);
        
    }
}

output
Employee emp details
1 Krishna Arjun AP India
New Employee newEmp details
1 Krishna Arjun AP India

                                                 Home

No comments:

Post a Comment