Java Externalization Example

By Arvind Rai, January 08, 2023
On this page we will learn to use java.io.Externalizable interface in our Java application.
1. Java provides Externalizable interface to externalize an instance. If a class implements Externalizable interface, then by default only the identity of the instance of this class is written in serialization stream and to save and restore the contents of this instance, it needs to be done by class itself using writeExternal and readExternal methods of the Externalizable interface.
2. The Externalizable interface is used by a class for the complete control over the format and contents of the stream for an objects and its supertype. The Externalizable interface provides writeExternal and readExternal methods to save and restore the data and these methods have to explicitly coordinate with the supertype to save its state.
3. The writeExternal and readExternal methods of Externalizable interface, supersede customized implementations of writeObject and readObject methods used in serialization by Serializable interface.
4. Object serialization as well as the persistence uses the Serializable and Externalizable interfaces. Each object to be stored, if supports Externalizable, then writeExternal method is called. If the object does not support Externalizable, then it is checked if the class implements Serializable interface, if yes, then object is saved using ObjectOutputStream.
5. When an Externalizable object is restored, first it is reconstructed using public no-arg constructor and then its readExternal method is called. In case of Serializable objects, they are restored by reading them from an ObjectInputStream.

Externalizable vs Serializable

1. When using Serializable interface, we get the serialization capability automatically. The object and its contents are serialized by default. For custom handing of serialization and deserialization, we can use writeObject and readObject method.
The Externalizable interface provides complete control of serialization and deserialization using its writeExternal and readExternal methods.

2. The class implementing Serializable interface needs to explicitly declare a serialVersionUID and if not declared, then the serialization runtime will calculate a default serialVersionUID value.
The class implementing Externalizable interface does not need such UID.

3. During serialization using Serializable interface, non-serializable sub-types can be serialized and deserialized, but no data will be written for the fields of non-serializable super classes.
In Externalization, the writeExternal and readExternal methods have to explicitly coordinate with the super type to save its state.

4. The Serializable interface is a marker interface and it has no methods.
The Externalizable interface has two methods that are the writeExternal and readExternal.

5. The Serializable uses reflection to construct object and does not require no-arg constructor.
The Externalizable needs public no-arg constructor to construct the object.

Methods of Externalizable Interface

The Externalizable interface has following methods.
1. writeExternal
void writeExternal(ObjectOutput out) throws IOException 
The object implements this method to save its content. For primitive data, this method calls the methods of DataOutput. For objects, strings, and arrays, this method calls the writeObject method of ObjectOutput.
Example:
public void writeExternal(ObjectOutput out) throws IOException {
  out.writeObject(userName);
  out.writeInt(age);
  out.writeBoolean(isActive);
  out.writeChar(gender);
} 

2. readExternal
void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 
The object implements this method to restore its contents. For primitive data, this method calls the methods of DataInput. For objects, strings, and arrays, this method calls the readObject method of ObjectInput.
Example:
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  userName = (String) in.readObject();
  age = in.readInt();
  isActive = in.readBoolean();
  gender = in.readChar();
} 
The readExternal method must read the values in the same sequence and with the same types as were written by writeExternal method.

Example

User.Java
package com.concretepage;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class User implements Externalizable {
  private String userName;
  private int age;
  private boolean isActive;
  private char gender;
  private String city;

  public User() {
  }

  @Override
  public void writeExternal(ObjectOutput out) throws IOException {
	out.writeObject(userName);
	out.writeInt(age);
	out.writeBoolean(isActive);
	out.writeChar(gender);
        // We are not writing 'city'
  }

  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
	userName = (String) in.readObject();
	age = in.readInt();
	isActive = in.readBoolean();
        gender = in.readChar();
        // We are not reading 'city'
  }

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public int getAge() {
    return age;
  }

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

  public boolean isActive() {
    return isActive;
  }

  public void setActive(boolean isActive) {
    this.isActive = isActive;
  }

  public char getGender() {
    return gender;
  }

  public void setGender(char gender) {
    this.gender = gender;
  }

  public String getCity() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }
  
  @Override
  public String toString() {
    return "userName: " + userName + ", age: " + age + ", isActive: " + isActive
    	+ ", gender: " + gender + ", city: " + city;
  }
} 
In the User class, we have 'userName', 'age', 'isActive', 'gender' and 'city' fields. We are saving and restoring all fields except 'city' fields.
CpMain.java
package com.concretepage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class CpMain {
  public static void main(String... args) throws Exception, IOException {
	// Saving object
	String file = "myfile.txt";
	File f = new File(file);

	FileOutputStream fout = new FileOutputStream(f);
	ObjectOutputStream out = new ObjectOutputStream(fout);

	User userToSave = new User();
	userToSave.setUserName("Mohan");
	userToSave.setAge(25);
	userToSave.setActive(true);
	userToSave.setGender('m');
	userToSave.setCity("Varanasi");
	
	out.writeObject(userToSave);

	out.flush();
	out.close();
	fout.close();

	// Restoring object
	FileInputStream foin = new FileInputStream(f);
	ObjectInputStream oin = new ObjectInputStream(foin);

	User userRestored =	(User) oin.readObject();

	oin.close();
	foin.close();
	System.out.println(userRestored);
  }
} 
Output
userName: Mohan, age: 25, isActive: true, gender: m, city: null 

Reference

Interface Externalizable
Interface Serializable
POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us