Serialization and Deserialization in Java (original) (raw)

Serialization and Deserialization are important Java mechanisms used to convert objects into a byte stream and reconstruct them back into objects. Together, they enable object persistence, data transfer, and communication between different systems while preserving an object's state.

Serialization

The serialization process converts a Java object into a byte stream, allowing it to be stored or transmitted while preserving its state. Since the generated byte stream is platform-independent, an object serialized on one platform can be deserialized on another platform.

**Deserialization

The deserialization process converts a byte stream back into its original Java object, restoring the object's state and data. This allows previously serialized objects to be retrieved and used within the application.

Visual Representation of Serialization and Deserialization Process

The image below demonstrates the process of serialization and deserialization.

Steps in Serialization

**Method Used for Serialization:

public final void writeObject(Object obj) throws IOException

Steps in Deserialization

**Method Used for Deserialization:

public final Object readObject() throws IOException, ClassNotFoundException

Advantages of Deserialization

Serializable Interface and Marker Interfaces

The Serializable interface is used to make a Java class eligible for serialization. Only objects of classes that implement the java.io.Serializable interface can be serialized and converted into a byte stream.

A marker interface is an interface that does not contain any methods or fields. It is used to provide special information to the JVM or compiler about a class's capabilities.

Points to remember while using Serialization:

**Example:

class A implements Serializable{
// B also implements Serializable
// interface.
B ob=new B();
}

SerialVersionUID

SerialVersionUID is a unique version identifier for a Serializable class. During deserialization, it ensures that the serialized object and the corresponding class have compatible versions.

**Syntax:

private static final long serialVersionUID = 3L;

serialver Tool

The serialver tool is provided with the JDK and is used to generate or display the serialVersionUID value of a Serializable class.

Example of Getting SerialVersionUID using Serialver

We can run the following command to get serialVersionUID serialver [-classpath classpath] [-show] [classname
**Example: Serialization and Deserialization of a Java Object.

Java `

import java.io.*;

class Demo implements Serializable { public int a; public String b;

public Demo(int a, String b) {
    this.a = a;
    this.b = b;
}

}

public class Geeks { public static void main(String[] args) { Demo object = new Demo(1, "geeksforgeeks"); String filename = "file.ser";

    // Serialization
    try {
        FileOutputStream file = new FileOutputStream(filename);
        ObjectOutputStream out = new ObjectOutputStream(file);
        out.writeObject(object);
        out.close();
        file.close();
        System.out.println("Object has been serialized");

    } catch (IOException ex) {
        System.out.println("IOException is caught");
    }

    Demo object1 = null;

    // Deserialization
    try {
        FileInputStream file = new FileInputStream(filename);
        ObjectInputStream in = new ObjectInputStream(file);
        object1 = (Demo) in.readObject();
        in.close();
        file.close();
        System.out.println("Object has been deserialized");
        System.out.println("a = " + object1.a);
        System.out.println("b = " + object1.b);

    } catch (IOException ex) {
        System.out.println("IOException is caught");
    } catch (ClassNotFoundException ex) {
        System.out.println("ClassNotFoundException is caught");
    }
}

}

`

**Output:

OutputSerialization1

**Example: Serialization with Transient and Static Fields.

Java `

import java.io.*;

class Emp implements Serializable { private static final long serialVersionUID = 129348938L; transient int a; static int b; String name; int age;

public Emp(String name, int age, int a, int b) {
    this.name = name;
    this.age = age;
    this.a = a;
    this.b = b;
}

}

public class Geeks{ public static void printData(Emp object1) { System.out.println("name = " + object1.name); System.out.println("age = " + object1.age); System.out.println("a = " + object1.a); System.out.println("b = " + object1.b); }

public static void main(String[] args) {
    Emp object = new Emp("ab", 20, 2, 1000);
    String filename = "shubham.txt";

    // Serialization
    try {
        // Saving of object in a file
        FileOutputStream file = new FileOutputStream(filename);
        ObjectOutputStream out = new ObjectOutputStream(file);
        out.writeObject(object);
        out.close();
        file.close();
        System.out.println("Object has been serialized\nData before Deserialization.");
        printData(object);

        // Change static variable b
        object.b = 2000;

    } catch (IOException ex) {
        System.out.println("IOException is caught");
    }

    object = null;

    // Deserialization
    try {
        // Reading the object from a file
        FileInputStream file = new FileInputStream(filename);
        ObjectInputStream in = new ObjectInputStream(file);
        object = (Emp) in.readObject();
        in.close();
        file.close();
        System.out.println("Object has been deserialized\nData after Deserialization.");
        printData(object);

    } catch (IOException ex) {
        System.out.println("IOException is caught");
    } catch (ClassNotFoundException ex) {
        System.out.println("ClassNotFoundException is caught");
    }
}

}

`

Output

Object has been serialized Data before Deserialization. name = ab age = 20 a = 2 b = 1000 Object has been deserialized Data after Deserialization. name = ab age = 20 a = 0 b = 2000

**Explanation In the above code while deserializing the object the values of a and b has changed. The reason being a was marked as transient and b was static.

**Transient Vs Final

The main difference between Transient and Final is listed below:

**Example:

final int x= 10;
int y = 20;
System.out.println(x);// compiler will replace this as System.out.println(10)->10
because x is final.
System.out.println(y);//20

**Example: Demonstration of transient and final behaviour together while serialization.

Java `

import java.io.*;

class Dog implements Serializable{ int i=10; transient final int j=20; } class Geeks { public static void main (String[] args)throws IOException, ClassNotFoundException { Dog d1=new Dog(); //Serialization started

      System.out.println("serialization started");
      
      FileOutputStream fos= new FileOutputStream("abc.ser");
      ObjectOutputStream oos=new ObjectOutputStream(fos);
      
      oos.writeObject(d1);
      System.out.println("Serialization ended");
  
      //Deserialization started
      System.out.println("Deserialization started");
      FileInputStream fis=new FileInputStream("abc.ser");
      ObjectInputStream ois=new ObjectInputStream(fis);
      Dog d2=(Dog) ois.readObject();
      System.out.println("Deserialization ended");
      System.out.println("Dog object data");
      //final result
      System.out.println(d2.i+"\t" +d2.j);
}

}

`

Output

serialization started Serialization ended Deserialization started Deserialization ended Dog object data 10 20

Serialization vs Deserialization

Feature Serialization Deserialization
**Definition Process of converting a Java object into a byte stream. Process of converting a byte stream back into a Java object.
**Purpose Used to save or transmit an object's state. Used to restore and use a previously saved object.
**Direction Object -> Byte Stream Byte Stream -> Object
**Main Class Used ObjectOutputStream ObjectInputStream
**Method Used writeObject() readObject()
**Output Serialized byte stream. Reconstructed Java object.
**Common Use Cases File storage, caching, network communication. Reading stored data, object recovery, data transfer.
**Exception Handling May throw IOException. May throw IOException and ClassNotFoundException.
**Constructor Invocation Constructor is used when creating the original object. Constructor is not called during deserialization.