Serialization and Deserialization in Java

Serialization and Deserialization in Java

In this article, I am going to discuss the Serialization and Deserialization of an object in Java with Examples. Please read our previous article where we discussed Character Streams in Java in detail. As part of this article, we are going to discuss the following pointers in detail which are related to Java Serialization and Deserialization.

  1. What are Object Files?
  2. What is Serializable Interface in Java?
  3. What is Serialization and Deserialization in Java?
  4. What is the difference between High-level stream and low-level stream?
  5. What is the difference between Complete Serialization and Selective serialization and how can we achieve it?
  6. What is the marker interface?
  7. What is the need for a marker interface?
  8. Understanding the transient Keyword in Java
  9. Console Class in Java

Before understanding Serialization and Deserialization in java, let us first understand what is an object file and why do we need to serialize and deserialize an object file in java application.

What are Object Files?

The object file is a collection of different types of objects. To create the object files we have to take the help of streams like ObjectOutputStream, ObjectInputStream, etc. To write the object or read the object then the particular object must be serialized.

An object can be said to be serialized only when its class implementing Serializable Interface. If we are reading or writing any object which is not serialized then JVM will throw a run time error or Exception saying NotSerializableException.

What is Serializable Interface in Java?

Serializable is an interface defined in the java.io package with zero methods. If an interface is defined with zero methods(has no data member and methods) then it is called a marked interface or tagged interface.

The main job of a marked or tagged interface is providing instructions to JVM to perform a special task. Example: Cloneable, Serializable, EventListener, etc.

If we are declaring a class by implementing a serializable interface then we are giving an instruction to the JVM to allow us to read the object from and write the object into object files.

Note: In small applications, the industry generally prefers serialization and deserialization persistence operations on the files.

What is Serialization in Java?

The process of capturing object data and writing that data into a file is called as serializable. In other words, Serialization is a process of converting the object into a stream of bytes which is nothing but writing the object into an object file. For better understanding please have a look at the following image.

What is Serialization in Java?

In serialization process objects will not be written to a file but the data of that object will be written to a file. To perform this serialization we can use a class called ObjectOutputStream. It is mainly used in Hibernate, RMI, JPA, EJB, and JMS technologies.

Creation of ObjectOutputStream : ObjectOutputStream oos = new ObjectOutputStream(OutputStream);

Advantages of Serialization
  1. To save/persist the state of an object.
  2. It is mainly used to travel the object’s state on the network (which is known as marshaling).
What is Deserialization in Java?

The process of reading data from a file and constructing a new java object having those data is called de-serialization. Or we can say that the reverse process of creating an object from a sequence of bytes is called deserialization. For better understanding, please have a look at the following image.

What is Deserialization in Java?

Deserialization is a process of converting a stream of bytes into an object which is nothing but reading the object from an object file. To perform this deserialization we use the class called ObjectInputstream.

Creation of ObjectInputStream: ObjectInputstream ois = new ObjectInputStream(InputStream);

A stream is a continuous flow of data that represents the communication channel between the application and destination resource (file). Byte stream can read and write bytes. Character stream can read and write characters.

Serialization and Deserialization in Java

Points to Remember:

If a parent class has implemented a Serializable interface then the child class doesn’t need to implement it but vice-versa is not true. Only non-static data members are saved via the Serialization process. Static data members and transient data members are not saved via the Serialization process. So, if you don’t want to save the value of a non-static data member then make it transient.

The constructor of object is never called when an object is deserialized. Associated objects must be implementing the Serializable interface.

What is the difference between High-level stream and low-level stream?

The High-level streams interact with files through low-level streams and can work with data like string values and object values, etc.

What is the difference between High level stream and low level stream?

The Low-level streams interact with files directly and can deal with low-level data like characters and bytes.

Serialization and Deserialization in Java

Note: java objects becomes Serializable only when the class of that object implements java.io.Serializable marker interface.

Syntax:
import java.io.Serializable;
public class Student implements Serializable 
{
 int sno;
 String name;
 float avg;
}

The object of this class is to support only complete serialization.

import java.io.Serializable;
public class Student implements Serializable 
{
 int sno;
 String name;
 Static/transient float avg;
}

The object of this class support only selective serialization

What is the difference between Complete Serialization and Selective serialization and how can we achieve it?

If entire data of an object is written to a file then that is called complete serialization. On the other hand, if partial data of an object is written to a file then that is called selective serialization.

If a class is having static or transient variables then the object of that class supports only selective serialization. Static member variables allocate memory outside the object so they do not participate in serialization.

The transient member variable allocates the memory inside the object but they will be marked for not participating in object serialization.

Sample Program demonstrating the Serialization and DeSerialization of an Object

Student.java

Let us create a Student Class.

import java.io.*;
public class Student implements Serializable {
 int rno;
 String name;
 String address;
 Student(int rno, String name, String address){
  this.rno = rno;
  this.name = name;
  this.address = address;
 }
 void display() {
  System.out.println(rno+"\t"+name+"\t"+address);
 }
}
SerializationDemo.java

Here, we are going to serialize the object of the Student class. The writeObject() method of ObjectOutputStream class provides the functionality to serialize the object. We are saving the state of the object in the file named file.txt.

Create SerializationDemo Class and then copy and paste the below code in it.

import java.io.*;
public class SerializationDemo
{
    public static void main (String args[]) throws IOException
    {
        //create object for student
        Student s = new Student (7, "Sachin", "Delhi");
        
        //low level stream
        FileOutputStream fos = new FileOutputStream ("file.txt");
        
        //high level stream
        ObjectOutputStream oos = new ObjectOutputStream (fos);
        
        //perform serializatio
        //capture student object data and writes that data to a file
        oos.writeObject (s);
        System.out.println ("Object is written");
        
        //close stream
        oos.close ();
        fos.close();
    }
}

Output: Object is written

Understanding writeObject() method

Three important statements

  1. If java method parameter type is java class name then we can call that method by having that class or one of its subclass objects as argument values.
  2. If java method parameter type is abstract class name then we can call that method having one subclass object of that abstract class as an argument type.
  3. If java method parameter type is interface name then we can call that method with one implementation class object of that interface.
DeSerializationDemo.java

Here, we are reading the data from a deserialized object. create DeSerializationDemo Class and then copy and paste the below code in it.

import java.io.*;
public class DeSerializationDemo
{
    public static void main (String[]args) throws IOException,
    ClassNotFoundException
    {
        FileInputStream fis = new FileInputStream ("file.txt");
        ObjectInputStream ois = new ObjectInputStream (fis);
        Student s = (Student) ois.readObject ();
        s.display ();
        ois.close ();
    }
}

Output: 7 Sachin Delhi

Understanding readObject() method:

Three important points

  1. If the java method return type is the concrete class name then that method can return either that concrete class object or one of its subclass objects.
  2. If java method return type is interface name then that method returns one implementation class object of that interface.
  3. If the java method return type is abstract class name then that method returns one subclass object of that abstract class.
Points to Remember:
  1. There is no terminology called selective deserialization. The object data that is returned through the serialization process must be retrieved through the deserialization process.
  2. The structure of the class must be the same while performing serialization and deserialization operations. Otherwise, the serialization process raises java.io.InvalidClassException.
  3. In order to send Java objects over the network, it must be designed as a serializable object.
  4. All wrapper class objects and collection framework data structures are serializable by default.
What is the marker interface?

An interface that is used to check/mark/tag the given object is of a specific type to perform special operations on that object is called a marker interface. Marker interface will not have methods, they are empty interfaces.

What is the need for a marker interface?

It is used to check whether we can perform some special operations on the passed object or not. For example: if a class is deriving from java.io.Serializable, then that class object can be serializable, else it cannot. If a class is deriving from java.lang.Clonable, then that class object can be cloned, else it cannot.

Inside those particular methods, that method developer will check that the passed object is of the type the given interface or not by using instanceof operator.

transient Keyword in Java

We can transfer an object from one location to another location only when the corresponding object is serialized. When we transfer an object from one location to another location then all the object data will be transferred.

But if you don’t want to transfer a few values of the object then the variables are declared using a java keyword or modifier called “transient” which are called transient variables. Transient variables are the variables which cannot participate in the serialization.

When we transfer the transient variables then it will hide the original value and transfer the default values.

Rules for using transient keyword
  1. There is no effect using the transient keyword on static variables because static variables are class variables and they never participate in serialization.
  2. There is no effect using the transient keyword on final variables because final variables always participate in serialization.
  3. The transient keyword can be applied only on instance variables.
  4. The transient keyword cannot be applied to classes, methods, interfaces, local variables.
Console Class

This class is used to read the data from the keyboard or write the data on to monitor. This class will be used in Console based applications (which are running on command prompt and it is introduced in Java 1.6 version.

This class contains a special method called readPassword(). We cannot create an object for the Console class directly because it contains a private constructor. But we can create an object for Console class using a method called system.console()

Creating a Console Object: Console c = System.console();

Sample Program:
public class ConsoleDemo 
{
    public static void main(String args[])  
    { 
        String str; 
          
        //Obtaining a reference to the console. 
        Console con = System.console(); 
          
        // Checking If there is no console available, then exit. 
        if(con == null)  
        { 
            System.out.print("No console available"); 
            return; 
        } 
          
        // Read a string and then display it. 
        str = con.readLine("Enter your name: "); 
        con.printf("Here is your name: %s\n", str); 
  
        //to read password and then display it 
        System.out.println("Enter the password: "); 
        char[] ch=con.readPassword(); 
  
        //converting char array into string 
        String pass = String.valueOf(ch); 
        System.out.println("Password is: " + pass); 
    } 
}

Output:

Java Serialization and Deserialization

SerialVersionUID

The serialization process at runtime associates an id with each Serializable class which is known as SerialVersionUID. It is used to verify the sender and receiver of the serialized object. The sender and receiver must be the same. To verify it, SerialVersionUID is used. The sender and receiver must have the same SerialVersionUID, otherwise, InvalidClassException will be thrown when you deserialize the object. We can also declare our own SerialVersionUID in the Serializable class. To do so, you need to create a field SerialVersionUID and assign a value to it. It is suggested to explicitly declare the serialVersionUID field in the class and have it private also. It must be static, final, and of type long.

i.e- ANY-ACCESS-MODIFIER static final long serialVersionUID=42L;

If a serializable class doesn’t explicitly declare a serialVersionUID, then the serialization runtime will calculate a default one for that class based on various aspects of the class, as described in Java Object Serialization Specification.

In the next article, I am going to discuss the Arrays in Java in detail with examples. Here, in this article, I try to explain Java Serialization and Deserialization. I hope you enjoy this Java Serialization and Deserialization article. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

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