Transient keyword with Serialization in Java

In this article, we will discuss transient keyword or modifier with serialization in detail

 

Whenever, we talk about Serialization then definitely there will be loads of questions on transient keyword

Also, it’s one of the favorite interview questions in Java

 

 

Serialization process

During serialization process i.e.; saving the state of an Object to File, all instance variables will be participated and persisted to file storage

 

Instance variable: all member variables/attributes of an Object without any modifiers like static

 

What if we don’t want to serialize specific variable/attributes for security or any other reasons?

  • The answer is declare respective member instance variable with transient modifier
  • Yes, we can stop persisting specific variable during serialization process by declaring transient modifier (for that specific variable)

 

Transient keyword

  • Transient keyword or modifier is applicable only for variables
  • We can stop persisting specific variable, by declaring transient keyword
  • During serialization, JVM ignores the original value of transient variable and saves default value to file
  • Examples: Customer SSN or password need not to be stored. Hence, it’s a good practice to declare those variables as transient
  • So whenever we encounter transient keyword, it means that not to serialize

 

Demo example on Transient keyword

For objects to participate in serialization & de-serialization process, corresponding class should implement java.io.Serializable interface

Exception: otherwise, run time exception will be thrown stating NotSerializableException

 

 

Step 1: Create POJO which implements java.io.Serializable interface

In Customer POJO, there are 4 member variables with customerSSN declared with transient keyword

Which means, during serialization instead of original value, default value will be saved to file and this can be proved by de-serializing the serialized object

 

Customer.java

package in.bench.resources.serialization;

import java.io.Serializable;

public class Customer implements Serializable {

	// member variables
	int customerId;
	String customerName;
	int customerAge;
	transient int customerSSN;


	// 4-arg parameterized constructor
	public Customer(int customerId, String customerName,
			int customerAge, int customerSSN) {
		super();
		this.customerId = customerId;
		this.customerName = customerName;
		this.customerAge = customerAge;
		this.customerAge = customerAge;
	}

	// overriding toString() method
	@Override
	public String toString() {
		return "Customer [customerId=" + customerId 
				+ ", customerName=" + customerName 
				+ ", customerAge="  + customerAge
				+ ", customerSSN=" + customerSSN + "]";
	}
}

 

 

Step 2: Main program to demonstrate serialization/de-serialization

To Serialize: any Object, we can use ObjectOutputStream & FileOutputStream to write/save to the file (in binary format)

To De-Serialize: any Object, we can use ObjectInputStream & FileInputStream to read/restore from file (which is in binary format) into Java heap memory

 

TransientDemo.java

package in.bench.resources.serialization;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class TransientDemo {

	public static void main(String[] args) {

		// create an customer instance using 4-arg constructor
		Customer serializeCustomer = 
				new Customer(102, "SR", 17, 112569);

		// creating output stream variables
		FileOutputStream fos = null;
		ObjectOutputStream oos = null;

		// creating input stream variables
		FileInputStream fis = null;
		ObjectInputStream ois = null;

		// creating customer object reference 
		// to hold values after de-serialization 
		Customer deSerializeCustomer = null;

		try {
			// for writing or saving binary data
			fos = new FileOutputStream("Customer.ser");

			// converting java-object to binary-format 
			oos = new ObjectOutputStream(fos);

			// writing or saving customer object's value to stream
			oos.writeObject(serializeCustomer);
			oos.flush();
			oos.close();

			System.out.println("Serialization success: Customer "
					+ "object saved to Customer.ser file\n");

			// reading binary data
			fis = new FileInputStream("Customer.ser");

			// converting binary-data to java-object
			ois = new ObjectInputStream(fis);

			// reading object's value and casting to Customer class
			deSerializeCustomer = (Customer) ois.readObject();
			ois.close();

			System.out.println("De-Serialization success: Customer "
					+ "object de-serialized from Customer.ser file\n");
		} 
		catch (FileNotFoundException fnfex) {
			fnfex.printStackTrace();
		}
		catch (IOException ioex) {
			ioex.printStackTrace();
		}
		catch (ClassNotFoundException ccex) {
			ccex.printStackTrace();
		}

		// printing customer object to console using toString() method
		System.out.println("Printing customer values from "
				+ "de-serialized object... \n" + deSerializeCustomer);
	}
}

Output:

Serialization success: Customer object saved to Customer.ser file

De-Serialization success: Customer object de-serialized 
from Customer.ser file

Printing customer values from de-serialized object... 
Customer [customerId=102, customerName=SR, customerAge=17, customerSSN=0]

 

Explanation:

  • In above Customer POJO, customerSSN declared as transient
  • So during serialization process, original value of customerSSN won’t be saved to file
  • Instead default value will be saved (i.e.; 0 for int, null for String, etc)
  • 1st half of the program illustrate serialization process
  • And 2nd half deals with de-serialization process, which de-serializes the serialized Object
  • While de-serializing all instance member values are re-stored back perfectly except for customerSSN
  • Reason: because this is marked with transient keyword

 

So, by declaring instance variable with transient keyword we can restrict to store that particular variable into file storage during serialization process

And it depends purely on business requirement that, which all the instance variables need to be restricted

 

 

References:

https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
https://docs.oracle.com/javase/7/docs/platform/serialization/spec/serial-arch.html
https://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html
https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html
https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html
https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.3

 

Happy Coding !!
Happy Learning !!