Before understanding Externalizable interface, you need
to have idea about Serialization.You can read more about Serialization
at Serialization in java.
Java provides mechanism called serialization to persists java objects in a form of ordered or sequence of bytes that includes the object’s data as well as information about the object’s type and the types of data stored in the object.
Now lets see how serialization happens:
At sender side:
JVM checks if class implements externalizable or not.If it does then serialize object using writeExternal() method.If it does not implement externalizable but implements serializable , object is serialized using ObjectOutputStream.
At receiver side:
When object is reconstructed and it is externalizable , an instance is created using no args constructor and readExternal is called.If it is not externalizable but serializable , object is reconstructed using ObjectInputStream.
Lets start with example same as we have used in Serialization in java.
Create Employee.java in src->org.arpit.java2blog
Employee.java:
you must have no args contructor if you implement externalizable.
Do you really want this much overhead when all you want to serialize is employeeId and employeeNameJava provides mechanism called serialization to persists java objects in a form of ordered or sequence of bytes that includes the object’s data as well as information about the object’s type and the types of data stored in the object.
Externalizable:
As name suggest it is externalilizing your serialization.If you want to customize your serialization mechanism then you can use it.It uses custom written mechanism to perform marshalling and unmarshalling of objects.Externalizable interface extends Serializable interface. If you implement this interface then you need to override following methods.- @Override
- public void readExternal(ObjectInput arg0) throws IOException,
- ClassNotFoundException {
- }
- @Override
- public void writeExternal(ObjectOutput arg0) throws IOException {
- }
At sender side:
JVM checks if class implements externalizable or not.If it does then serialize object using writeExternal() method.If it does not implement externalizable but implements serializable , object is serialized using ObjectOutputStream.
At receiver side:
When object is reconstructed and it is externalizable , an instance is created using no args constructor and readExternal is called.If it is not externalizable but serializable , object is reconstructed using ObjectInputStream.
Lets start with example same as we have used in Serialization in java.
Create Employee.java in src->org.arpit.java2blog
Employee.java:
- package org.arpit.java2blog;
- import java.io.Externalizable;
- import java.io.IOException;
- import java.io.ObjectInput;
- import java.io.ObjectOutput;
- public class Employee implements Externalizable{
- int employeeId;
- String employeeName;
- String department;
- String nationality;
- public Employee()
- {
- }
- public int getEmployeeId() {
- return employeeId;
- }
- public void setEmployeeId(int employeeId) {
- this.employeeId = employeeId;
- }
- public String getEmployeeName() {
- return employeeName;
- }
- public void setEmployeeName(String employeeName) {
- this.employeeName = employeeName;
- }
- public String getDepartment() {
- return department;
- }
- public void setDepartment(String department) {
- this.department = department;
- }
- public String getNationality() {
- return nationality;
- }
- public void setNationality(String nationality) {
- this.nationality = nationality;
- }
- @Override
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- employeeId=in.readInt();
- employeeName=(String) in.readObject();
- }
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeInt(employeeId);
- out.writeObject(employeeName);
- }
- }
Create ExternalizableMain.java in org.arpit.java2blog
ExternalizableMain.java:
- package org.arpit.java2blog;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- public class ExternalizableMain {
- /**
- * @author Arpit Mandliya
- */
- public static void main(String[] args) {
- Employee emp = new Employee();
- emp.setEmployeeId(101);
- emp.setEmployeeName(“Arpit”);
- emp.setDepartment(“CS”);
- //Serialize
- try
- {
- FileOutputStream fileOut = new FileOutputStream(“employee.ser”);
- ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
- outStream.writeObject(emp);
- outStream.close();
- fileOut.close();
- }catch(IOException i)
- {
- i.printStackTrace();
- }
- //Deserialize
- emp = null;
- try
- {
- FileInputStream fileIn =new FileInputStream(“employee.ser”);
- ObjectInputStream in = new ObjectInputStream(fileIn);
- emp = (Employee) in.readObject();
- in.close();
- fileIn.close();
- }catch(IOException i)
- {
- i.printStackTrace();
- return;
- }catch(ClassNotFoundException c)
- {
- System.out.println(“Employee class not found”);
- c.printStackTrace();
- return;
- }
- System.out.println(“Deserialized Employee…”);
- System.out.println(“Emp id: “ + emp.getEmployeeId());
- System.out.println(“Name: “ + emp.getEmployeeName());
- }
- }
Run it :
When you run ExternalizableMain.java.You will get following output- Deserialized Employee…
- Emp id: 101
- Name: Arpit
If you already have serializable,why you need externalizable at all!!:
- When you serialize any object using serializable, apart from fields,
all objects that belong to object map and that can be reached using
instance variable will also be serialized .for example :
- If you have Employee class and its superclass is person then it will serialize all superclass objects (such as person) until it reaches “Object” class.
- Similarly if Employee has instance variable of address class then it will serialize whole object map of address also .
- JVM uses reflection when you use serializable which is quite slow.
- While serializing,information about class description which incluses description of its superclass and instance variable associated with that class also get stored in stream.Again this is also a performance issue
Inheritance in Externalization:
Now we will see how inheritance affects externalization.So there can be muliple cases whether super class is externalizable or not.If not then how will you handle that and how it works.Lets see by example.We will create Person.java which will be superclass of Employee.

Case 1: What if super class does not implement Externalizable:
If superclass does not implements externalizable , you need to
serialize superclass ‘s fields in subclass that implements
Externalizable.
Person.java- package org.arpit.java2blog;
- public class Person {
- String name=“default”;
- String nationality;
- public Person()
- {
- System.out.println(“Person:Constructor”);
- }
- public Person(String name, String nationality) {
- super();
- this.name = name;
- this.nationality = nationality;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getNationality() {
- return nationality;
- }
- public void setNationality(String nationality) {
- this.nationality = nationality;
- }
- }
Employee.java:
- package org.arpit.java2blog;
- import java.io.Externalizable;
- import java.io.IOException;
- import java.io.ObjectInput;
- import java.io.ObjectOutput;
- ;
- public class Employee extends Person implements Externalizable{
- int employeeId;
- String department;
- public Employee()
- {
- }
- public Employee(int employeeId,String name,String department,String nationality)
- {
- super(name,nationality);
- this.employeeId=employeeId;
- this.department=department;
- System.out.println(“Employee:Constructor”);
- }
- public int getEmployeeId() {
- return employeeId;
- }
- public void setEmployeeId(int employeeId) {
- this.employeeId = employeeId;
- }
- public String getDepartment() {
- return department;
- }
- public void setDepartment(String department) {
- this.department = department;
- }
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- /*since superclass does not implement externalizable, you need to serialize super class field in this class itself*/
- //superclass fields
- out.writeObject(name);
- out.writeObject(nationality);
- // its own fields
- out.writeInt(employeeId);
- out.writeObject(department);
- }
- @Override
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- /*since superclass does not implement externalizable, you need to deserialize super class field in this class itself*/
- //superclass fields
- name=(String) in.readObject();
- nationality=(String) in.readObject();
- // its own fields
- employeeId=in.readInt();
- department=(String) in.readObject();
- }
- }
Create ExternalizableMain.java in org.arpit.java2blog
ExternalizableMain.java:- package org.arpit.java2blog;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- public class ExternalizableMain {
- /**
- * @author Arpit Mandliya
- */
- public static void main(String[] args) {
- //Serialize
- Employee emp = new Employee(101,“Arpit”,“CS”,“Indian”);
- System.out.println(“Before serializing”);
- System.out.println(“Emp id: “ + emp.getEmployeeId());
- System.out.println(“Name: “ + emp.getName());
- System.out.println(“Department: “ + emp.getDepartment());
- System.out.println(“Nationality: “ + emp.getNationality());
- System.out.println(“************”);
- System.out.println(“Serializing”);
- try
- {
- FileOutputStream fileOut = new FileOutputStream(“employee.ser”);
- ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
- outStream.writeObject(emp);
- outStream.close();
- fileOut.close();
- }catch(IOException i)
- {
- i.printStackTrace();
- }
- //Deserialize
- System.out.println(“************”);
- System.out.println(“Deserializing”);
- emp = null;
- try
- {
- FileInputStream fileIn =new FileInputStream(“employee.ser”);
- ObjectInputStream in = new ObjectInputStream(fileIn);
- emp = (Employee) in.readObject();
- in.close();
- fileIn.close();
- }catch(IOException i)
- {
- i.printStackTrace();
- return;
- }catch(ClassNotFoundException c)
- {
- System.out.println(“Employee class not found”);
- c.printStackTrace();
- return;
- }
- System.out.println(“After serializing”);
- System.out.println(“Emp id: “ + emp.getEmployeeId());
- System.out.println(“Name: “ + emp.getName());
- System.out.println(“Department: “ + emp.getDepartment());
- System.out.println(“Nationality: “ + emp.getNationality());
- }
- }
Run it :
When you run ExternalizableMain.java.You will get following output:- Employee:Constructor
- Before serializing
- Emp id: 101
- Name: Arpit
- Department: CS
- Nationality: Indian
- ************
- Serializing
- ************
- Deserializing
- Person:Constructor
- After serializing
- Emp id: 101
- Name: Arpit
- Department: CS
- Nationality: Indian
Case 2: What if super class implements Externalizable:
If superclass implements externalizable ,then it will also have
readExternal() and writeExternal() method so it will serialize its own
fields in these methods
Person.java- package org.arpit.java2blog;
- import java.io.Externalizable;
- import java.io.IOException;
- import java.io.ObjectInput;
- import java.io.ObjectOutput;
- public class Person implements Externalizable{
- String name=“default”;
- String nationality;
- public Person()
- {
- System.out.println(“Person:Constructor”);
- }
- public Person(String name, String nationality) {
- super();
- this.name = name;
- this.nationality = nationality;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getNationality() {
- return nationality;
- }
- public void setNationality(String nationality) {
- this.nationality = nationality;
- }
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(name);
- out.writeObject(nationality);
- }
- @Override
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- name=(String) in.readObject();
- nationality=(String) in.readObject();
- }
- }
Employee.java:
- package org.arpit.java2blog;
- import java.io.Externalizable;
- import java.io.IOException;
- import java.io.ObjectInput;
- import java.io.ObjectOutput;
- ;
- public class Employee extends Person implements Externalizable{
- int employeeId;
- String department;
- public Employee()
- {
- }
- public Employee(int employeeId,String name,String department,String nationality)
- {
- super(name,nationality);
- this.employeeId=employeeId;
- this.department=department;
- System.out.println(“Employee:Constructor”);
- }
- public int getEmployeeId() {
- return employeeId;
- }
- public void setEmployeeId(int employeeId) {
- this.employeeId = employeeId;
- }
- public String getDepartment() {
- return department;
- }
- public void setDepartment(String department) {
- this.department = department;
- }
- @Override
- public void writeExternal(ObjectOutput out) throws IOException {
- super.writeExternal(out);
- out.writeInt(employeeId);
- out.writeObject(department);
- }
- @Override
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- super.readExternal(in);
- employeeId=in.readInt();
- department=(String) in.readObject();
- }
- }
Create ExternalizableMain.java in org.arpit.java2blog
ExternalizableMain.java:- package org.arpit.java2blog;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- public class ExternalizableMain {
- /**
- * @author Arpit Mandliya
- */
- public static void main(String[] args) {
- //Serialize
- Employee emp = new Employee(101,“Arpit”,“CS”,“Indian”);
- System.out.println(“Before serializing”);
- System.out.println(“Emp id: “ + emp.getEmployeeId());
- System.out.println(“Name: “ + emp.getName());
- System.out.println(“Department: “ + emp.getDepartment());
- System.out.println(“Nationality: “ + emp.getNationality());
- System.out.println(“************”);
- System.out.println(“Serializing”);
- try
- {
- FileOutputStream fileOut = new FileOutputStream(“employee.ser”);
- ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
- outStream.writeObject(emp);
- outStream.close();
- fileOut.close();
- }catch(IOException i)
- {
- i.printStackTrace();
- }
- //Deserialize
- System.out.println(“************”);
- System.out.println(“Deserializing”);
- emp = null;
- try
- {
- FileInputStream fileIn =new FileInputStream(“employee.ser”);
- ObjectInputStream in = new ObjectInputStream(fileIn);
- emp = (Employee) in.readObject();
- in.close();
- fileIn.close();
- }catch(IOException i)
- {
- i.printStackTrace();
- return;
- }catch(ClassNotFoundException c)
- {
- System.out.println(“Employee class not found”);
- c.printStackTrace();
- return;
- }
- System.out.println(“After serializing”);
- System.out.println(“Emp id: “ + emp.getEmployeeId());
- System.out.println(“Name: “ + emp.getName());
- System.out.println(“Department: “ + emp.getDepartment());
- System.out.println(“Nationality: “ + emp.getNationality());
- }
- }
Run it :
When you run ExternalizableMain.java.You will get following output:- Employee:Constructor
- Before serializing
- Emp id: 101
- Name: Arpit
- Department: CS
- Nationality: Indian
- ************
- Serializing
- ************
- Deserializing
- Person:Constructor
- After serializing
- Emp id: 101
- Name: Arpit
- Department: CS
- Nationality: Indian
DownSides of Externalizable:
- If you make any change to your class definition, you need to maintain writeExternal() and readExternal accordingly.
- As we have seen in example,Sub class object has to coordinate with its superclass to save and store its state(by call super.xxxx() method from subclass)
For more Visit: http://www.quontrasolutions.com/blog/category/java
No comments:
Post a Comment