Externalizable

java.io.Externalizable Example

In this tutorial we will discuss about the Externalizable interface in Java. The Externalizable interface provides a way to implement a custom serialization mechanism. A class that implements the Externalizable interface is responsible to save and restore the contents of its own instances.

Furthermore, the Externalizable interface extends the Serializable interface and provides two methods to serialize and de-serialize an object, writeExternal and readExternal.

Finally, the Externalizable interface exists since the 1.1 version of Java.

 

The Structure of the Externalizable interface

Methods

An object implements this method, in order to restore its state. The readExternal method must read all values, along with their types, in the same sequence and format, as they were written by the writeExternal method. Finally, for primitive types, the methods of the ObjectInput class are called, while for objects, string and arrays, the readObject method is sufficient.

An object must implement this method, in order to store its state. For primitive types, the methods of the ObjectOutput class are called, while for objects, string and arrays, the writeObject method is sufficient.

The Externalizable interface in Java

By implementing both the writeExternal and readExternal methods, a class gains complete control over the format and the contents that will be serialized.

The procedure of serializing an object uses both the Externalizable and Serializable interface interfaces. If an object implements the Externalizable interface, then, its writeExternal method is called. Otherwise, the object is persisted using the ObjectOutputStream class.

Regarding the procedure of de-serialization, initially, an instance is created using the public constructor, which contains no arguments at all. Then, if the object implements the Externalizable interface, the readExternal method is called. Otherwise, the object is created by reading its content from an instance of the ObjectInputStream class.

A sample example that demonstrates how to serialize an object that implements the Serializable interface is presented below:

SerializableExample.java:

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

class SerializablePair implements Serializable {
	private static final long serialVersionUID = 2616423033716253195L;

	private String key = null;
	private String value = null;
	
	public SerializablePair(String key, String value) {
		this.key = key;
		this.value = value;
	}
	
	@Override
	public String toString() {
		return "Pair ";
	}
}

public class SerializableExample {
	private final static String OUTPUT_FILE = "serializable_file";
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		SerializablePair pair = new SerializablePair("Hello", "World");
		System.out.println("Initially: " + pair.toString());

		// Serialize the pair to a file.
		FileOutputStream outputStream = new FileOutputStream(OUTPUT_FILE);
		ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
		objectOutputStream.writeObject(pair);

		// Close all resources.
		objectOutputStream.flush();
		outputStream.close();

		// Read the contents from the file and create a new instance.
		SerializablePair copyOfPair = null;

		FileInputStream inputStream = new FileInputStream(OUTPUT_FILE);
		ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
		copyOfPair = (SerializablePair) objectInputStream.readObject();

		// Close all resources.
		objectInputStream.close();
		inputStream.close();
		
		System.out.println("After de-serialization: " + copyOfPair.toString());
	}
}

In this example, we define a new class, called SerializablePair that implements the Serializable interface and then, serialize and de-serialize it properly. A sample execution is shown below:

Initially: Pair 
After de-serialization: Pair 

A sample example that demonstrates how to serialize an object that implements the Externalizable interface is presented below:

ExternalizableExample.java:

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 ExternalizablePair implements Externalizable {
	private String key;
	private String value;
	
	public ExternalizablePair() {
		this.key = null;
		this.value = null;
	}
	
	public ExternalizablePair(String key, String value) {
		this.key = key;
		this.value = value;
	}
	
	@Override
	public String toString() {
		return "Pair ";
	}

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

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

public class ExternalizableExample {
private final static String OUTPUT_FILE = "externalizable_file";
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		ExternalizablePair pair = new ExternalizablePair("Hello", "World");
		System.out.println("Initially: " + pair.toString());

		// Serialize the pair to a file.
		FileOutputStream outputStream = new FileOutputStream(OUTPUT_FILE);
		ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
		pair.writeExternal(objectOutputStream);

		// Close all resources.
		objectOutputStream.flush();
		outputStream.close();

		// Read the contents from the file and create a new instance.
		ExternalizablePair copyOfPair = new ExternalizablePair();

		FileInputStream inputStream = new FileInputStream(OUTPUT_FILE);
		ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
		copyOfPair.readExternal(objectInputStream);

		// Close all resources.
		objectInputStream.close();
		inputStream.close();
		
		System.out.println("After de-serialization: " + copyOfPair.toString());
	}
}

In this example, we define a new class, called ExternalizablePair that implements the Externalizable interface and then, serialize and de-serialize it properly. A sample execution is shown below:

A sample execution is shown below:

Initially: Pair 
After de-serialization: Pair 

However, the implemention of the Externalizable interface must take place with caution, since there are some fundamental characteristics:

  • First of all, if a class implements the Serializable interface, then the Java Virtual Machine (JVM) is responsible for its automatic serialization. Otherwise, if a class implements the Externalizable interface, the developer and maintainer of a class is responsible for its serialization.
  • Second, the Externalizable interface poses the challenge of how to serialize the super type state, default values in case of transient variables and finally, static variables.
  • Third, in case a class implements the Externalizable inteface and a single field is changed, both the writeExternal and readExternal methods must be upgraded.

Download the Eclipse Project

This was a tutorial about the Externalizable interface in Java.

Download
You can download the full source code of this example here: JavaExternalizableInterfaceExample.zip.

Sotirios-Efstathios Maneas

Sotirios-Efstathios (Stathis) Maneas is a PhD student at the Department of Computer Science at the University of Toronto. His main interests include distributed systems, storage systems, file systems, and operating systems.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button