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 theExternalizable
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 thewriteExternal
andreadExternal
methods must be upgraded.
Download the Eclipse Project
This was a tutorial about the Externalizable
interface in Java.
You can download the full source code of this example here: JavaExternalizableInterfaceExample.zip.