Externalization in Java

What is Externalization?

Externalization is simply an advanced form of serialization.By serialization we can convert an object to a byte stream  and can be written to a file. Later the byte stream can be converted back to the same object.For more details please read the   Serialization tutorial.The serialization in java is having few drawbacks.

Performance overhead:Serialization uses the default serialization algorithm.In serialization , serialVersionUID is important. If  it is not specified , it will be calculated by inspecting the entire attributes of the class.It is surely an overburden. Similarly ,to serialize an object , all the member attributes needs to be serialized.Suppose a member attribute is  an object of another class in our application, and it is a subclass of some other class.In this scenario the serialization process is not so easy.

Initialization in constructor is not so easy :Suppose we created a new object  from byte stream read from a file. In this case the default constructor  of the class will not be invoked.There are ways to invoke the constructor , but the person who does the coding  should take care about it.

Now in Externalization we are implementing the Externalizable interface.Unlike the Serializable interface , it is not a marker interface.It has two methods :  writeExternal() and readExternal(). In these methods we can specify the way in which the object is to be persisted. For more details let us discuss an example.Here I am trying to externalize an Employee object.

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

public class Employee implements Externalizable {
private static final long serialVersionUID = 2L;
private int id;
private String name;
private String department;
private double expLevel;

public Employee() {

}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getDepartment() {
return department;
}

public void setDepartment(String department) {
this.department = department;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public double getExpLevel() {
return expLevel;
}

public void setExpLevel(double expLevel) {
this.expLevel = expLevel;
}

public void writeExternal(ObjectOutput objectOutput) throws IOException {
objectOutput.writeInt(getId());
objectOutput.writeUTF(getName());
objectOutput.writeUTF(getDepartment());
objectOutput.writeDouble(getExpLevel());

}

public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
id = objectInput.readInt();
name = objectInput.readUTF();
department = objectInput.readUTF();
expLevel = objectInput.readDouble();

}
}

Now let us see the main to do the externalization process. Here I am using a file /tmp/employeeExternal.txt  for persisting an Employee object. If your OS is  Windows ,then  the file will be created in the \tmp folder of the drive in which the workspace is located.Here we are creating an Employee object and writing that into file using writeExternal() method. Then reading it using readExternal() method.Remember , whatever order we used for writing   the individual attributes , the same should be used for reading too.

import java.io.*;

public class EmployeeMain {
public static void main(String[] args) {
File file = new File("/tmp/employeeExternal.txt");
Employee employee = new Employee();
employee.setId(1);
employee.setName("Bijoy");
employee.setDepartment("Instrumentation");
employee.setExpLevel(2.0);
System.out.println("Before externalization = " + employee.getId() + " ; " + employee.getName() + " ; " + employee.getDepartment()
+ " ; " + employee.getExpLevel());
try {
ObjectOutputStream oStream = new ObjectOutputStream(new FileOutputStream(file));
employee.writeExternal(oStream);
oStream.flush();
oStream.close();
ObjectInputStream iStream = new ObjectInputStream(new FileInputStream(file));
Employee emp = new Employee();
emp.readExternal(iStream);
iStream.close();
System.out.println("output of externalization = " + emp.getId() + " ; " + emp.getName() + " ; " + emp.getDepartment()
+ " ; " + emp.getExpLevel());
} catch (FileNotFoundException fo) {
fo.printStackTrace();
} catch (IOException io) {
io.printStackTrace();
} catch (ClassNotFoundException cf) {
cf.printStackTrace();
}

}
}

Now let us see the output. The same data is retrieved .In this way externalization can be done.

Before externalization = 1 ; Bijoy ; Instrumentation ; 2.0

output of externalization = 1 ; Bijoy ; Instrumentation ; 2.0