27
Jan

How to implement Externalizable or custom serialization in Java

The default java serialization stores all properties/elements associated with an objeect and is is not efficient. It you serialize a bloated objected having lots of attributes and properties, you do not wish to serialize for any reason (e.g. they always been assigned default values), you get heavy object to process and send more bytes over network which may be costly on some cases.

To solve this issue, you can write your own serialization logic by implementing Externalizable interface and overriding it’s methods writeExternal() and readExternal(). By implementing these methods, you are telling the JVM how to encode/decode your object.




Externalization is used whenever we need to customize serialization mechanism. If a class implements an Externalizable interface then, object serialization will be done using writeExternal() method. Whereas at receiver's end when an Externalizable object is a reconstructed instance will be created using no argument constructor and then the readExternal() method is called.

If a class implements only Serializable interface object serialization will be done using ObjectoutputStream. At the receiver's end, the serializable object is reconstructed using ObjectInputStream.

How to implement Externalizable or custom serialization in Java

Step 1: Sample class which implements Externalizable interface
=================================================================

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

public class MyClass implements Externalizable {

	// Empty constructor 
	public MyClass() {

	}

	private String name;

	private Integer age;
	private String address;
	private boolean isResident;

	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeUTF(this.getName());
	}

	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		this.name = in.readUTF();
	}

	@Override
	public String toString() {
		return "MyClass [name=" + name + ", age=" + age + ", address=" + address + ", isResident=" + isResident + "]";
	}

	public String getName() {
		return name;
	}

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

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public boolean isResident() {
		return isResident;
	}

	public void setResident(boolean isResident) {
		this.isResident = isResident;
	}
}




Step 2: Client for Externalizable
=====================================

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExternalizableClient {

	public static void main(String[] args) {
		MyClass obj = new MyClass();
		obj.setName("Sheetal");

		storeUserSettings(obj);

		MyClass obj2 = loadSettings();
		System.out.println(obj2.getName());

	}

	private static MyClass loadSettings() {
		try {
			FileInputStream fis = new FileInputStream("object.dat");
			ObjectInputStream ois = new ObjectInputStream(fis);
			MyClass settings = (MyClass) ois.readObject();
			ois.close();
			return settings;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static void storeUserSettings(MyClass obj) {
		try {
			FileOutputStream fos = new FileOutputStream("object.dat");
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(obj);
			oos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}


This will produce the following result −

Output
Sheetal