In this article, we will discuss how can we serialize and de-serialize member variables with transient modifier or keyword
In earlier articles, we have seen what happens to member variables when transient modifier applied to it. Read below articles to get more insights,
- Role of Transient modifier or keyword in Serialization
- Transient keyword with static variable in Serialization
- Transient keyword with final variable in Serialization
Let us re-phrase what exactly happens during serialization and de-serialization when transient modifier applied to member variables
1. Serialization process:
- During serialization process i.e.; saving state of an Object to File, only instance variables will be participated and persisted to file storage or some other storage via network capability
- So, when variable with transient modifier is encountered, then that variable’s original value is discarded and instead default value is stored into file storage
2. De-Serialization process:
- During de-serialization process, Object’s state will be restored back from file storage
- Likewise, when variable with transient modifier is encountered during restoring object back to heap memory from file storage then its default value is restored, as this is what stored into file storage
So far, we have seen all things related to transient modifier and the next question is,
Q) How can we serialize and de-serialize transient variables ?
- Well, answer is programmer has to write some custom logic by overriding below 2 methods i.e.;
1. writeObject();
2. readObject(); - Note : this is on top of default serialization and de-serialization process
Q) What happens by overriding 2 methods ?
- While serialization, writeObject() method is invoked automatically and all custom logic coded/written by programmer for writing/saving to file storage is executed
- Similarly while de-serialization, readObject() method is invoked automatically and all custom logic coded/written by programmer for restoring object back into heap memory from file storage is executed
Q) Write complete method signature of 2 methods ?
- The complete signature of writeObject() and readObject() methods is described below,
- Method signature :
private void writeObject(ObjectOutputStream objectOutputStream) throws Exception {
}
private void readObject(ObjectInputStream objectInputStream) throws Exception {
}
It’s time to play with Java code
3. Example for Serializing a variable with transient keyword:
We will write simple program covering how can we serialize and de-serialize objects involving member variables with transient modifier or keyword
3.1 Customer POJO i.e.; class to be serialized:
- Below Customer class consists of 3 member variables, out of which 2 are transient variable
- So, while serializing these 2 member variables won’t be serialized and similarly while retrieving/restoring during de-serialization process , their default values will be obtained back
- To serialize these 2 transient variables, we have to override 2 methods
writeObject(); –> for saving/writing in serialization process
readObject(); –> for restoring during de-serialization process
3.2 Custom Serialization:
- During serialization inside writeObject(); method, programmer has to do default serialization for saving actual customer object
- Then custom logic to write these 2 transient variables in encrypted form
3.2.1 Steps for serialization inside writeObject() method:
- Default serialization for saving/writing actual customer object
- Add integer ‘333’ to customer Id and use writeInt() method to save customer Id in encrypted form
- Similarly, add “Test” string to customer SSN number and use writeObject() method to save customer SSN number in encrypted form
3.3 Custom De-Serialization:
- During de-serialization inside readObject(); method, programmer has to do default de-serialization for restoring actual customer object
- Then custom logic to read these 2 transient variables in encrypted form (by decrypting)
3.3.1 Steps for de-serialization inside readObject() method:
- Default de-serialization for restoring/retrieving actual customer object
- Use readInt() method to retrieve customer Id in encrypted form and decrypt by subtracting integer ‘333’ from customer Id
- Similarly, use readObject() method to retrieve customer SSN number in encrypted form and decrypt by using String handling functionalities (like substring at index 4)
Customer.java
package in.bench.resources.custom.serialization;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Customer implements Serializable {
// member variables for Customer
transient int customerId;
String customerName;
transient String customerSSN;
// 3-arg parameterized constructor for Customer
public Customer(int customerId, String customerName,
String customerSSN) {
super();
this.customerId = customerId;
this.customerName = customerName;
this.customerSSN = customerSSN;
}
// to print nicely - customer object
@Override
public String toString() {
return "Customer ["
+ "customerId=" + customerId
+ ", customerName=" + customerName
+ ", customerSSN=" + customerSSN
+ "]";
}
/**
* this method invoked automatically during serialization process
*
* @param objectOutputStream
* @throws Exception
*/
private void writeObject(ObjectOutputStream objectOutputStream)
throws Exception {
// 1st do, save using default serialization for all objects
objectOutputStream.defaultWriteObject();
// temp variable
int tempCustId = 333 + customerId;
String tempCustSSN = "Test" + customerSSN;
// saving customer Id and SSN, in encrypted version
objectOutputStream.writeInt(tempCustId);
objectOutputStream.writeObject(tempCustSSN);
}
/**
* this method invoked automatically during de-serialization process
*
* @param objectInputStream
* @throws Exception
*/
private void readObject(ObjectInputStream objectInputStream)
throws Exception {
// 1st do, restore using default de-serialization for all objects
objectInputStream.defaultReadObject();
// temp variable
int tempCustId = objectInputStream.readInt();
String tempCustSSN = objectInputStream.readObject().toString();
// decrypting and restoring transient variables
customerId = tempCustId - 333;
customerSSN = tempCustSSN.substring(4);
}
}
3.4 Serialization and De-serialization:
This program is the test class to write/save customer object to file storage and then restoring for reading customer object
- 1st part explains, complete serialization process
- 2nd explains, complete de-serialization process
CustomerSerialization.java
package in.bench.resources.custom.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 CustomerSerialization {
public static void main(String[] args) {
// create an customer object using 3-arg parametrized constructor
Customer serializeCustomer = new Customer(102, "NK", "SSN-78087");
// 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: "
+ "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: 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: Customer object saved to Customer.ser file
De-Serialization: Customer object de-serialized from Customer.ser file
Printing customer values from de-serialized object...
Customer [customerId=102, customerName=NK, customerSSN=SSN-78087]
Related Articles:
- Java – Serialization and De-Serialization Tutorial Index
- Java – Introduction to Serialization and De-Serialization
- Java – Serializable interface
- Java – Transient keyword with Serialization
- Java – Transient keyword with static variable in Serialization
- Java – Transient keyword with final variable in Serialization
- Java – Serializing a variable with transient modifier or keyword
- Java – Order of Serialization and De-Serialization
- Java – Serialization with Aggregation
- Java – Serialization with Inheritance
- Java – Externalization in detail
- Java – Serializable v/s Externalizable
- Java – Importance of SerialVersionUID in Serialization
- Java – Singleton Design pattern with Serialization
- Java – How to construct a singleton class in a multi-threaded environment ?
- Java – Singleton design pattern, restricting Object creation by overriding readResolve() method
- Java – How to stop Serialization ?
- Java – How to serialize and de-serialize ArrayList ?
- Java – Interview question & answers on Serialization and Externalization
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 !!