This article helps you understand about externalization in Java with code examples. You will be able to implement externalization in your Java programs.

 

1. What is Externalization in Java?

In serialization, the Java Virtual Machine is totally responsible for the process of writing and reading objects. This is useful in most cases, as the programmers do not have to care about the underlying details of the serialization process. However, the default serialization does not protect sensitive information such as passwords and credentials, or what if the programmers want to secure some information during the serialization process?

Thus externalization comes to give the programmers full control in reading and writing objects during serialization.

 

2. The Externalizable Interface

When you want to control the process of reading and writing objects during the serialization and de-serialization process, have the object’s class implemented the java.io.Externalizable interface. Then you implement your own code to write object’s states in the writeExternal() method and read object’s states in the readExternal() method. These methods are defined by the Externalizableinterface as follows:

  • writeExternal(ObjectOutput out): The object implements this 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.
 

  • readExternal(ObjectInput in): The object implements this method to restore its contents by calling the methods of DataInput for primitive types and readObject for objects, strings and arrays.
Suppose that you have a class User, then implement externalization for this class as shown in the following example:

import java.io.*;

/**
 * Externalization example
 * @author www.codejava.net
 */
public class User implements Externalizable {
	// attributes

	// methods

	// externalization methods:

	public void writeExternal(ObjectOutput out) {
		// implement your own code to write objects of this class
	}

	public void readExternal(ObjectInput in) {
		// implement your own code to read serialized objects of this class
	}
}
Now, let’s see how to implement the writeExternal() and readExternal() methods in details.



Suppose that the User class has the following attributes:

import java.util.*;
import java.io.*;

/**	
 * Externalization example
 * @author www.codejava.net
 */
public class User implements Externalizable {
	public static final long serialVersionUID = 1234L;

	// attributes
	private int code;
	private String name;
	private String password;
	private Date birthday;
	private int socialSecurityNumber;

	public User() {
	}

	// methods (getters and setters)
	public int getCode() {
		return this.code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Date getBirthday() {
		return this.birthday;
	}

	public void setSocialSecurityNumber(int ssn) {
		this.socialSecurityNumber = ssn;
	}

	public int getSocialSecurityNumber() {
		return this.socialSecurityNumber;
	}
}
NOTE: It’s strongly recommended that all serializable classes define the serialVersionUID constant as declared in the User class above:

public static final long serialVersionUID = 1234L;
This helps the de-serialization process keeps re-constructing the objects correctly when the serializable classes get changed overtime, and avoid the InvalidClassException.

 

3. Implementing writeExternal() method

As the writeExternal() method takes an ObjectOutput, we can use its method to write object’s states into the underlying stream follow these rules:

  • For primitive types, use the writeXXX() methods of the DataOutput interface, such as writeBoolean(), writeByte(), writeInt(), writeLong(), etc.
  • For object types (Strings, arrays, your custom classes), use the writeObject() method.
Following the above rules, we implement the writeExternal() method of the User class above like the following code:

public void writeExternal(ObjectOutput out) throws IOException {
	out.writeInt(code);
	out.writeObject(name);

	// write empty password:
	out.writeObject("");

	out.writeObject(birthday);

}
As you can see, we serialize the following attributes: code, name, password and birthday. For security purpose, password is cleared and socialSecurityNumber is not serialized. This gives you the ideas of how we can control the process of serialization by implementing the Externalizable interface.

                          

4. Implementing readExternal() method

As the readExternal() method takes an ObjectInput, we can use its method to read object’s states from the underlying stream follow these rules:

  • For primitive types, use the readXXX() methods of the DataInput interface, such as readBoolean(), readByte(), readInt(), readLong(), etc.
  • For object types (Strings, arrays, your custom classes), use the readObject() method.
Following the above rules, we implement the readExternal() method of the User class above like the following code:

public void readExternal(ObjectInput in) throws ClassNotFoundException, IOException {
	this.code = in.readInt();
	this.name = (String) in.readObject();
	this.password = (String) in.readObject();
	this.birthday = (Date) in.readObject();
}
As you can see, we de-serialize the following attributes: code, name, password and birthday. The socialSecurityNumber is not de-serialized for security purpose. This gives you the ideas of how we can control the process of de-serialization by implementing the Externalizable interface.

 

5. Java Externalization Example Program

Here’s the full source code of the demo program:

import java.util.*;
import java.io.*;

/**
 * Externalization Demo Program.
 * @author www.codejava.net
 */
public class ExternalizationDemo {

	private String filePath = "user.ser";

	public void serialize() throws IOException {
		User user = new User();

		user.setCode(123);
		user.setName("Tom");
		user.setBirthday(new Date());
		user.setPassword("secret123");
		user.setSocialSecurityNumber(1234567890);


		// serialize object's state
		FileOutputStream fos = new FileOutputStream(filePath);
		ObjectOutputStream outputStream = new ObjectOutputStream(fos);
		outputStream.writeObject(user);
		outputStream.close();


		System.out.println("User's details before serialization:\n" + user);
		System.out.println("Serialization done");
	}

	public void deserialize() throws ClassNotFoundException, IOException {
		FileInputStream fis = new FileInputStream(filePath);
		ObjectInputStream inputStream = new ObjectInputStream(fis);
		User user = (User) inputStream.readObject();
		inputStream.close();

		System.out.println("User's details afeter de-serialization:\n" + user);
	}

	public static void main(String[] args)
			throws ClassNotFoundException, IOException {
		ExternalizationDemo demo = new ExternalizationDemo();

		demo.serialize();

		System.out.println("\n=============\n");

		demo.deserialize();

	}

}
And override the toString() method in the User class:

public String toString() {
	String details = "Code: " + code;
	details += "\nName: " + name;
	details += "\nBirthday: " + birthday;
	details += "\nPassword: " + password;
	details += "\nSSN: " + socialSecurityNumber;

	return details;
}
Run the above program and we have the following output:

User's details before serialization:
Code: 123
Name: Tom
Birthday: Sat Mar 19 15:12:27 ICT 2016
Password: secret123
SSN: 1234567890
Serialization done

=============

User's details afeter de-serialization:
Code: 123
Name: Tom
Birthday: Sat Mar 19 15:12:27 ICT 2016
Password:
SSN: 0
As you can see in the output, the password gets blank and social security number is reset after de-serialization.

 

API References:

 

Related Tutorials:

 

Other Java File IO Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (ExternalizationDemo.zip)ExternalizationDemo.zip[Java Externalization Demo Program]1 kB

Add comment

   


Comments 

#2Piyush Kashyap2020-04-13 14:26
helpful article. Thanks.
Quote
#1Sai2018-10-19 06:55
JVM checks if class implements externalizable or not.If it does then serialize object using writeExternal() method.If it does not implement externalizable but implements serializable , object is serialized using ObjectOutputStream. At receiver side: ... Lets start with example same as we have used in Serialization in java.
Quote