Serialization and Deserialization in Java

Serialization and Deserialization in Java

Image Explanation: Serialization and Deserialization in Java

Serialization in Java

Serialization is the process of converting an object’s state (its fields and their values) into a byte stream that can be easily transmitted over the network or can be saved to a file, or can be stored in a database.The reverse process of serialization is known as deserialization . In deserialization, the byte-stream is converted into an object.  

Serialization and deserialization processes are platform-independent which means an object can be serialized on one platform and can be deserialized on a different platform.

Serialization in Java

In Java, serialization is achieved by implementing java.io.Serializable interface.  Serialization is a markup interface; Markup interface is also known as a Tag interface. This type of interface does not have any method or constant inside it. It gives instruction to JVM to apply special behaviors or characteristics to the implemented class.

Syntax to implement Serialization: 
<Modifier> class <className>  implements java.io.Serializable {
}

Example of Serialization : Here we are making Student class serialized by implementing  java.io.Serializable interface.

Student class Serialized :
import java.io.Serializable;
public class Student implements Serializable{
   	private String name;
	private int age;
	private String address;
    	public Student(String name, int age, String address) {
          	this.name = name;
    	this.age = age;
    	this.address = address;
   	}
    	@Override
   	public String toString() {
          	return "Student [Name: " + name + ", Age: " +age+ ", Address :" + address + "]";
   	}
}

Test Student Serialized class

  1. Create new Student object by implementing Serializable interface (As created in above example)
  2. Create a test class as we created StudentSerializeExample for testing
  3. Write Student object into the a file
  4. Verify Student object is created in file.
  5. You can also verify by deserializing the object.
Save Student class object in file  (Serialization)
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream; 
public class StudentSerializeExample {
   	public static void main(String[] args) {
          	Student student = new Student("Alice", 20, "India");
          	File testFile = new File("abc.txt");
          	try (FileOutputStream fileOut = new FileOutputStream(testFile);
                       	ObjectOutputStream out = new ObjectOutputStream(fileOut)) { 
                 	out.writeObject(student);
                 	System.out.println("Student object is saved in abc.txt file");
           	} catch (IOException e) {
                 	e.printStackTrace();
          	}
   	}
}


Output:
1.On console printed message is : Student object is saved in abc.txt file
2. Student object is written in abc.txt file.

  If you will not implement Serializable interface at runtime you will get exception (java.io.NotSerializableException )because Student class is not serializable . like in below example, Studnet class is not implementing Serializable interface.

package com.rtt.learn;
public class Student{
	private String name;
    private int age;
    private String address;
public Student(String name, int age, String address) {
		this.name = name;
        this.age = age;
        this.address = address;
	}

	public Student(String name, int age) {
		this.name = name;
        this.age = age;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Override
	public String toString() {
		return "Student [Name: " + name + ", Age: " +age+ ", Address :" + address + "]";
	}
		
}

Serializable test class
package com.rtt.learn;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;


public class StudentSerializeExample {

	public static void main(String[] args) {
		Student student = new Student("Alice", 30, "India");
		saveInfile(student);		
	}

	private static void saveInfile(Student student) {
		File testFile = new File("abc.txt");
		try (FileOutputStream fileOut = new FileOutputStream(testFile);
				ObjectOutputStream out = new ObjectOutputStream(fileOut)) {

			out.writeObject(student);
			System.out.println("Student object is saved in abc.txt file");

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

java.io.NotSerializableException: com.rtt.learn.Student
	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
	at java.io.ObjectOutputStream.writeObject(Unknown Source)
	at com.rtt.learn.StudentSerializeExample.saveInfile(StudentSerializeExample.java:26)
	at com.rtt.learn.StudentSerializeExample.main(StudentSerializeExample.java:18)

Why Serialization is Important

Serialization is particularly important when you need to:

  1. Object Persistence: Serialization is commonly used to store objects in a way that allows them to be retrieved later, even after the Java application has been closed and restarted. This is especially useful for saving user preferences, configuration settings, and application state.

  2. Network Communication: When sending objects over a network connection, serialization is used to convert the object into a byte stream that can be transmitted and then deserialized on the receiving end in readable format.

  3. Caching: Serialization is also used in caching mechanisms. Serialized objects can be stored in memory to reduce latency and to improve application performance.

  4. Message Queues and Event Sourcing: In event-driven architectures, serialization is used to process messages to message queues or event logs.

Serialization Rules

  1. Implement Serializable: To make a class serializable, it must implement the java.io.Serializable interface.

  2. Serializable Fields: All instance variables (fields) of a serializable class are automatically serialized.

  3. Transient field :  If you do not want to make any variable/field to be serialized, mark that as transient.

  4. Static Variable : static variables are not serialized.  Static variables belong to class level not to instance level. Since In Serialization process, data associated with instance  of a class is serialized that is why static fields are ignored during this process

  5.  Parent Class Serialized : If parent class is serialized then child class will automatically be serialized.

  6. Parent class not Serialized : If parent class is not serialized but child class is serialized then JVM ignores the original value of super class instance variable and saves the default value in the serialization process.

  7. Aggregation : Serialized class’s object would not be serialized if any of its reference class is not serialized, If you try to do so, you will get java.io.NotSerializableException for not serializable class reference.
Like in the below example 

School class is not serialized, but Student a serialized class has reference of School class. If you try to serialize/deserialize Student class object, you will observe  java.io.NotSerializableException for School class.

public class School {
	private String schoolName;
}
public class Student  implements Serializable{
	private static final long serialVersionUID = 1L;
	private String name;
    private int age;
    public String address;
    private School school;
}

8. SerialVersionUID : it is always recommended to include long type serial version unique id  in the class to uniquely identify class version. SerialVersonUID is  defined as a static, final and long value in the class.

private static final long serialVersionUID = 1L;

Deserialization in Java

Deserialization is a reverse process of serialization, which means converting back serialized byte stream into an object with its data and structure. This allows you to restore the state of an object as it was when it was serialized. Just like serialization, deserialization is essential when reading persisted objects or receiving objects over a network.

Deserialization in Java

Deserialization Rules

  1. Class Availability: The class of the serialized object must be available in the classpath during deserialization. If the class is not found, a ClassNotFoundException will be thrown.

  2. Version Compatibility: Class structure remains compatible between the time of serialization and deserialization. If changes are made to the class’s structure, like adding or removing fields, it can lead to InvalidClassException during deserialization. serialVersionUID is recommended to use to maintain version compatibility.

  3. Version UID Matching: Unique serialVersionUID is defined in the class for error free serialization and deserialization process. 
    JDK serialver tool can be used to get the serialversionUID of the class.

Deserialization Example in Java

Here’s an example of how you might deserialize a Person object:

Create Student class Serialized 

import java.io.Serializable;
public class Student implements Serializable{
   	private String name;
	private int age;
	private String address;
 
   	public Student(String name, int age, String address) {
          	this.name = name;
    	this.age = age;
    	this.address = address;
   	}
 
   	@Override
   	public String toString() {
          	return "Student [Name: " + name + ", Age: " +age+ ", Address :" + address + "]";
   	}
}
Save Student class object in file (Serialization)
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class StudentSerializeExample {
	public static void main(String[] args) {
		Student student = new Student("RoundTheTech", 10, "India" );
		saveInfile(student);		
	}

	private static void saveInfile(Student student) {
		File testFile = new File("abc.txt");
		try (FileOutputStream fileOut = new FileOutputStream(testFile);
				ObjectOutputStream out = new ObjectOutputStream(fileOut)) {

			out.writeObject(student);
			System.out.println("Student object is saved in abc.txt file");

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

Output:
Student object is saved in abc.txt file
Verify abc.txt file. Student object should be written in the file.
Read Student object from file  (DeSerialization)

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class StudentDeSerializeExample {

	public static void main(String[] args) {
		readFromFile();
	}

	private static void readFromFile() {
		File testFile = new File("abc.txt");

		try (FileInputStream fileIn = new FileInputStream(testFile);
				ObjectInputStream in = new ObjectInputStream(fileIn)) {

			Student deserializedStudent = (Student) in.readObject();
			System.out.println("Deserialized Student object: " + deserializedStudent);

		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}


Output:
Deserialized Student object: Student [Name: RoundTheTech, Age: 10, Address :India]

SerialVersionUID

serialVersionUID  is a long unique version identifier that is associated with each serialized class. It acts as a version control number of the serialized class. Serialization and Deserialization process uses the same unique serial version identifier to perform error free serialization and deserialization of the object.

The default serialVersionUID computation mechanism is sensitive and depends on many factors like Compiler Implementation, class fields, fields type, access modifier, parent interface or class etc.

It is always recommended to give SerialVersionUID in your serialized class.  If you give SerialVersionUID, it will remain the same during serialization and deserialization process irrespective of any change in class or compiler implementation. 

If we do not give explicit serialVersionUID in class,Java Runtime will create an auto generated  serialVersionUID using Compiler Implementation, class fields, fields type, access modifier, etc and associate it with the class and  Serialization process happens using this auto generated serialVersionUID 

Suppose later we make the changes in class like add/remove something from class, default serialVersionUID will be changed. 

Since new and earlier serialVersionUID Id are different, you will get error java.io.InvalidClassException, If try to deserialize that object
JDK provides a serialver tool to know the serialVersionUID of the serialized class.

How To know the serialVersionUID of the class using command prompt

  1. Open command prompt
  2. Go to your JDK bin directory
  3. Type command serialver -classpath < classes folder where your .class files resides>  <class name with package> and enter
  4. You can see serialVersionUID of your class
SerialVersionUID

SerialVersionUID

Conclusion

  1. Serialization and deserialization are core concepts in Java that enable object persistence, data sharing, and network communication
  2. Need to  implement java.io.Serializable interface to create Serializable class
  3. If you do not want to make any variable/field serializable. Mark that as transient
  4. Static fields are ignored during serialization process
  5. It is always recommended to give  private static final long serialVersionUID in your class 
  6. You can use serialver tool to get the serialversionUID of serialized class.
  7. If parent class is serialized then the child class will automatically be serialized.
  8. If parent class is not serialized but child class is serialized then JVM ignores the original value of super class and saves the default value
  9. Serialized class’s object would not be serialized if any of its reference class is not serialized
  10. Deserialization allows you to retrieve and restore objects that were previously serialized and saved to persistent storage, such as files or databases.

P.S. We welcome your feedback. Please comment, if you find anything incorrect, or want to share more information about the topic or want to share any kind of feedback.

Leave a Reply

Your email address will not be published. Required fields are marked *