Learnitweb

Externalization in Java

Externalizable interface extends java.io.Serializable interface. Externalizable interface is used to provide the implementing class complete control over the format and contents of the stream for an object and its supertypes. Externalization in Java is used for customized serialization. If you want to control the process of reading and writing the objects during serialization and de-serialization process, you can user the interface java.io.Externalizable. There are two methods defined in Externalizable interface, readExternal and writeExternal. These methods supersede customized implementations of writeObject and readObject methods. If you want to serialize only part of an object, then Externalization is the best option.

There are many scenarios when you do not want to serialize some sensitive parts of the object, like passwords. Externalization is a perfect choice in such case.

Externalizable interface defines two methods:

void readExternal(ObjectInput in)
void writeExternal(ObjectOutput out)
  • Externalization is faster as Externalizable classes need less recursion, as you can identify which fields you need.
  • Externalizable objects can only be implemented for objects with a public default constructor. So non-static inner classes are not Externalizable.
  • When you modify the object in future, Externalizable classes will require a code change in your read/write method.
  • Using Externalization you can save part of an object.
  • In Externalization there is no effect of using transient keyword.
  • At the time of deserialization JVM will create a separate new object by executing public no-arg constructor on that object. Every Externalizable class should contain public no-arg constructor otherwise “InvaidClassException” exception is thrown.

In the following Externalization example, we are saving only id and username fields.

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;

class External implements Externalizable{
	int id;
	String username;
	String password;
	
	public External() {
		System.out.println("inside no-arg constructor");
	}

	public External(int id, String username, String password) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
	}
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(username);  
		out.writeInt(id); 
	} 
	
	public void readExternal(ObjectInput in)  throws  IOException , ClassNotFoundException {  
		username=(String)in.readObject();  
		id= in.readInt(); 
	} 
}

public class ExternalizationExample {
	public static void main(String args[]) throws Exception {
		External extObj=new  External(10, "James", "xyz@123"); 
		FileOutputStream fos=new FileOutputStream("test.ser"); 
		ObjectOutputStream oos=new ObjectOutputStream(fos); 
		oos.writeObject(extObj); 
		 
		FileInputStream fis=new FileInputStream("test.ser"); 
		ObjectInputStream ois=new ObjectInputStream(fis); 
		External ext=(External)ois.readObject(); 
		System.out.println(ext.id);
		System.out.println(ext.username);
		System.out.println(ext.password);
	}
}

Output

inside no-arg constructor
10
James
null