Tuesday, September 11, 2012

Short explain of Externalization


Externalization is nothing but serialization but by implementing Externalizable interface to persist and restore the object. To externalize your object, you need to implement Externalizable interface that extends Serializable interface. Here only the identity of the class is written in the serialization stream and it is the responsibility of the class to save and restore the contents of its instances which means you will have complete control of what to serialize and what not to serialize. But with serialization the identity of all the classes, its superclasses, instance variables and then the contents for these items is written to the serialization stream. But to externalize an object, you need a default public constructor.
Unlike Serializable interface, Externalizable interface is not a marker interface and it provides two methods - writeExternal and readExternal. These methods are implemented by the class to give the class a complete control over the format and contents of the stream for an object and its supertypes. These methods must explicitly coordinate with the supertype to save its state. These methods supersede customized implementations of writeObject and readObject methods.
How serialization happens? JVM first checks for the Externalizable interface and if object supports Externalizable interface, then serializes the object using writeExternal method. If the object does not support Externalizable but implement Serializable, then the object is saved using ObjectOutputStream. Now when an Externalizable object is reconstructed, an instance is created first using the public no-arg constructor, then the readExternal method is called. Again if the object does not support Externalizable, then Serializable objects are restored by reading them from an ObjectInputStream.
 
/**
 * Externalizable Impl
 */
package com;

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 thanooj
 *
 */
public class Employee implements Externalizable {

    private int empId;
    private String firstName;
    private String lastName;
    private int age;
   
    public Employee() {}
   
    public Employee(int empId, String firstName, String lastName, int age) {
        super();
        this.empId = empId;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    /* (non-Javadoc)
     * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
     * Note: we need to follow the order of writeExternal did.
     */
    @Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        empId = in.readInt();
        firstName = (String)in.readObject();
        age = in.readInt();
    }

    /* (non-Javadoc)
     * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
     */
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(empId);
        out.writeObject(firstName);
        out.writeInt(age);
    }

    @Override
    public String toString() {
        return empId + " "+firstName+" "+lastName+" "+age;
    }
   
    public static void main(String[] args) {
        Employee empSe = new Employee(1, "rama", "sri", 29);
        Employee empDe = null;
        //serialize the car
        try {
            FileOutputStream fo = new FileOutputStream("tmp");
            ObjectOutputStream so = new ObjectOutputStream(fo);
            so.writeObject(empSe);
            so.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // de-serialize the Car
        try {
            FileInputStream fi = new FileInputStream("tmp");
            ObjectInputStream si = new ObjectInputStream(fi);         
            empDe = (Employee) si.readObject();
            System.out.println(empDe);
        }
        catch (Exception e) {
             e.printStackTrace();
        }
    }
}

output:
--------
1 rama null 29

Tuesday, September 4, 2012

Explained Singleton with SeDe of the Emp instance




/**
 * SeDe
 * Explained Cloning, Singleton and SeDe of the Emp instance.
 *
 * for readResolve() and writeReplace() method explanations look-
 * http://docs.oracle.com/javase/1.3/docs/guide/serialization/spec/serialTOC.doc.html
 *
 */
package com.sede;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * @author u2fv
 *
 */
class Test {

}

class Emp implements Serializable, Cloneable {
private int eNo;
private String eName;
private transient float sal;
private Test test;
private static Emp emp;

private Emp() {
this.eNo = 0;
this.eName = null;
this.sal = 0.0f;
}

private Emp(int eNo, String eName, float sal) {
super();
this.eNo = eNo;
this.eName = eName;
this.sal = sal;
}

public static synchronized Emp getInstance() {
System.out.println("inside getInstance()");
if (emp == null) {
emp = new Emp();
}
return emp;
}

public static synchronized Emp getInstance(int i, String name, float sal) {
System.out.println("inside getInstance(1,2,3)");
if (emp == null) {
emp = new Emp(1, "rama", 3.4f);
}
return emp;
}

private Object readResolve() throws ObjectStreamException {
System.out.println("inside readResolve()");
return emp;
}

private Object writeReplace() throws ObjectStreamException {
System.out.println("inside writeReplace()" + " " + emp);
return emp;
}

@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException(
"You have no privileges to clone Emp instance");
}

@Override
public String toString() {
return eNo + " " + eName + " " + sal;
}

}

class SeDe {

public void doSe(Emp emp) {
try {
FileOutputStream fOS = new FileOutputStream("Myfile.ser");
ObjectOutputStream oOS = new ObjectOutputStream(fOS);
oOS.writeObject(emp);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

public Emp doDe(Emp emp) {
try {
FileInputStream fOS = new FileInputStream("Myfile.ser");
ObjectInputStream oOS = new ObjectInputStream(fOS);
emp = (Emp) oOS.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return emp;
}

public Emp doDeSecondTime(Emp emp) {
try {
FileInputStream fOS = new FileInputStream("Myfile.ser");
ObjectInputStream oOS = new ObjectInputStream(fOS);
emp = (Emp) oOS.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return emp;
}
}

public class TestSeDe {

/**
* @param args
*/
public static void main(String[] args) {
// Emp emp = Emp.getInstance();
Emp emp = Emp.getInstance(1, "rama", 2.3f);
SeDe seDe = new SeDe();
seDe.doSe(emp);
emp = null;
emp = seDe.doDe(emp);
System.out.println(emp + " || hashCode: " + emp.hashCode());
Emp emp1 = null;
emp1 = seDe.doDeSecondTime(emp1);
System.out.println(emp1 + " || hashCode: " + emp1.hashCode());
}

}

Output:
--------