Java Externalizable

In this tutorial, We’ll discuss about java’s java.io.Externalizable interface. The main goal of this interface is to provide custom serialization and deserialization.

Before we go ahead, make sure you check out the Java Serialization article.

Externalizable Interface

The java.io.Externalizable Interface is the child of java.io.Serializable interface. Externalizable interface offercustomized serialization.

The Externalizable interface declares following two methods:

  • public void writeExternal(ObjectOutput out) throws IOException : For custom serialization
  • public void readExternal(ObjectInput in) throws IOException : For custom de-serialization

Any class that implements Externalizable interface should override the writeExternal()readExternal() methods. Here there is no JVM’s default serialization behavior. We should mention which attributes to be serialized and de-serialized.  Where as in the case of Serialization Interface, all the attributes are serialized by default.

Here we don’t need any special care of transient, static and final variables, Because here serialization and de-serialization is in our control, we can serialize and de-serialize what ever the attribute we want.

Externalization Interface needs Public No-Arg Constructor to reconstruct the object in the de-serialization process.

Even we can manually call writeExternal()readExternal() methods to do serialization and de-serialization process.

Serialization and Deserialization with Externalizable

First we need to define a domain class which implements Externalizable interface with it’s attributes. Here in our example we are defining Employee class with serialVersionUID, and instance variable, final variable, static variable, transient variable, no-arg constructor and arg constructor, toString(), writeExternal()readExternal() methods as shown below.

In the above example, comments explain each variable and their behavior clearly.

For serializing, In the writeExternal() method, we’re adding the object’s properties to the ObjectOutput stream. This has standard methods like writeObject() for String and writeInt() for the int and writeDouble() for double values.

Next, For de-serializing, In the readExternal() method, we’re reading from the ObjectInput stream using the readObject(), readInt(), readDouble() methods to read the properties in the same exact order in which they were written.

It’s a good practice to add the serialVersionUID manually. If this is absent, the JVM will automatically add one.

To serialize and de-serialize objects, We are going to use same Java API given ObjectInputStream and ObjectOutputStream which we used in the case of Serializable interface.

Output : When we run the above program, it will create a file Employee.ser” in the project directory. The same will be loaded in the de-serialization process.

————Employee Arg Constructor————
Before serialization => Employee [employeeId=1001, name=Sekhar Reddy, salary=99999.0, department=IT]
————writeExternal(ObjectOutput out)————
————Employee No-Arg Constructor————
In deserializtion – department : IT
After deserialization => Employee [employeeId=1001, name=Sekhar Reddy, salary=99999.0, department=Default Department]

As per the above output,

  • We can see that all instance, transient, static and final variables can be successfully serialized and de-serialized.
  • The public No-Arg constructor has invoked in the de-serialization process
  • The final variable department cannot be assigned after de-serialization.

Java Externalizable with Inheritance(is-a Relationship)

If parent class is Externalizable class, then by default child class is also Externalizable. Here we should override writeExternal()readExternal() methods in both parent and child class. Every subclass need to call their parent  writeExternal()readExternal() methods before they serialize their own attributes.

So we should implement the writeExternal(), readExternal() methods for every sub-class of the inheritance hierarchy.

Let’s look into the following example:

Output :

————-Parent Arg Constructor————-
————-Child Arg Constructor————-
————-Before serialization————-
parentVariable = Vidvaan-Parent
childVariable = Vidvaan-Child
————-Parent No-Arg Constructor————-
————-Child No-Arg Constructor————-
————-After deserialization————-
parentVariable = Vidvaan-Parent
childVariable = Vidvaan-Child

Note that we called super.writeExternal(out), super.readExternal(in) within child class methods to save/restore the parent class fields as well.

Note that while de-serialization Parent and Child no-arg constructors are invoked.

Externalizable vs Serializable

Let’s go through the key differences between the two interfaces:

FactorSerializableExternalizable
Serialization ResponsibilityJVM takes the responsibility of serialization and de-serializationDeveloper takes the responsibility of serialization and de-serialization
Methods marker interfaceContains two methods: writeExternal() and readExternal()
public No-Arg ConstructorNot Required(Uses reflection to reconstruct object in de-serialization process)Required (Uses no-arg constructor to reconstruct object in de-serialization process)
PerformanceSlowFast
Use CaseBest option for serialize the entire objectBest option for customized serialization
Scroll to Top