In a previous article Everything About Java Serialization Explained With Example, I explained how we can serialize/deserialize one object using
Serializable interface and also explain how we can customise the serialization process using
Disadvantages Of Java Serialization Process
But these customizations are not sufficient because JVM has full control of the serialization process and those customization logics are just additions to the default serialization process. We still have to use the default serialization logic by calling
readObject methods. And if do not call these default methods our object will not be serialized/deserialized.
The default serialization process is fully recursive. So whenever we try to serialize one object, the serialization process try to serialize all the fields (primitive and reference) with our class (except
transient fields). Which makes serialization a very slow process.
Now let’s assume we have an object with lots of fields which we do not want to serialize for some reasons (these fields will always be assigned with default values). With default serialization process we will have to make all these fields transient but it still will not be efficient because there will lot of checks to see if the fields are transient or not.
So as we can see there are lots of downside of the using default serialization process, like:
- Customizations to serialization are not sufficient because JVM has full control of the serialization process and our customization logics are just additions to the default serialization process.
- Default serialization process is fully recursive and slow.
- In order to not to serialize a field, we have to declare it transient and lots of transient fields will again make the process slow.
- We can not control how our fields will be serialized and deserialized.
- Default serialization process does not invoke constructors while creating the object so it can not call the initialization logic provided by the constructor.
What Is Externalization And Externalizable Interface
As we saw above that the default java serialization is not efficient. We can solve some of these issues by using
Externalizable interface instead of
We can write your own serialization logic by implementing the
Externalizable interface and overriding it’s methods
readExternal(). But with this approach, we will not get any kind of default serialization logic from JVM and it is up to us to provide the complete serialization and deserialization logic.
So it is very necessary to code the test these methods very carefully because it might break the serialization process. But the externalization process is very fast in comparison to the default serialization process if implemented properly.
We will use below
Employee class object as an example for the explanation:
How Serialization works with Externalizable Interface
As we can see above in our example
Employee class, we can write your own serialization logic by implementing the Externalizable interface and overriding its methods
The object can implement the writeExternal method to save its contents by calling the methods of DataOutput for its primitive values or calling the writeObject method of ObjectOutput for objects, strings, and arrays.
The object can implement the readExternal method to restore its contents by calling the methods of DataInput for primitive types and readObject for objects, strings and arrays. The readExternal method must read the values in the same sequence and with the same types as were written by writeExternal.
To serialize and deserialize our object to a file we need to follow the same procedure as we followed in the Serializable example which means calling
ObjectInputStream.readObject() as done in the following code:
Externalizable interface is a child interface of
Externalizable extends Serializable. So if we implement
Externalizable interface and override its
readExternal() methods then first preference is given to these methods over the default serialization mechanism provided by JVM. These methods supersede customized implementations of
readObject methods, So if we also provide
readObject() then they will be ignored.
In the serialization process, each object to be serialized is tested for the Externalizable interface. If the object supports Externalizable, the writeExternal method is called. If the object does not support Externalizable and does implement Serializable, the object is saved using ObjectOutputStream.
When an Externalizable object is reconstructed, an instance is created using the public no-arg constructor, then the readExternal method called. Serializable objects are restored by reading them from an ObjectInputStream.
- When an Externizable object is reconstructed, and object is created using public no-arg constructor before the readExternal method is called. If a public no-arg constructor is not present then a InvalidClassException is thrown at runtime.
- Using Externalizable, we can even serialize/deserialize transient variables, so declaring fields transient becomes unnecessary.
- Using Externalizable, we can even serialize/deserialize static variables if we need to.
An Externalizable instance can designate a substitution object via the writeReplace and readResolve methods documented in the Serializable interface.
Java serialization can also be used to deep clone an object. Java cloning is the most debatable topic in Java community and it surely does have its drawbacks but it is still the most popular and easy way of creating a copy of an object until that object is full filling mandatory conditions of Java cloning. I have covered cloning in details in a 3 article long Java Cloning Series which includes articles like Java Cloning And Types Of Cloning (Shallow And Deep) In Details With Example, Java Cloning – Copy Constructor Versus Cloning, Java Cloning – Even Copy Constructors Are Not Sufficient, go ahead and read them if you want to know more about cloning.
Differences between Externalizable vs Serializable
Let’s list down the main differences between Externalizable and Serializable interfaces in java.
You can find the complete source code for this article on this
Github Repository and please feel free to provide your valuable feedback.
Published on Java Code Geeks with permission by Naresh Joshi, partner at our JCG program. See the original article here: How to Customize Serialization In Java By Using Externalizable Interface
Opinions expressed by Java Code Geeks contributors are their own.