Java Serialization: Part 1

What, why, and how...

What is serialization

Serialization is the process of converting an object into a stream of bytes. Let's look at the below code snippet.

import java.io.Serializable;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Car implements Serializable {
  private String make;
  private int year;
  private static final long serialVersionUID = 1L;

  public Car(String make, int year) {
    this.make = make;
    this.year = year;
  }
  public String toString(){
    return String.format("Car make is: %s, Car year is: %d", this.make, this.year);
  }

  public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
    Car toyota = new Car("Toyota", 2021);
    Car honda = new Car("Honda", 2020);
    FileOutputStream fileOutputStream = new FileOutputStream("cars.txt");
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
    objectOutputStream.writeObject(toyota);
    objectOutputStream.writeObject(honda);
  }
}

We have a Car class which has some noticeable characteristics:

  1. Serializable interface: This is a marker interface i.e, it has no variables or methods. Classes that are to support serialization of their objects must implement this interface.

  2. serialVersionUID: It's a good practice to declare and initialise this static variable, as it helps JVM to identify which class to use during deserialization.

Inside the main function we are writing the serialised objects in a file named cars.txt

Why serialization

Often we are transferring data (states in java objects) over network. In which case, the object has to be converted into byte stream. Another use case might be when we are writing the state of object in some file on disk. Serialization is required to support both usecases.

How to serialize?

  1. Implement Serializable interface.

  2. Declare and initialise private static final long serialVersionUID = 1L;

Now, when we want to serialize we will call writeObject() method from ObjectOutputStream class

How to deserialize?

Suppose we are trying to read bytes sent to us over network, and we wish to consume the data inside an object. For example, trying to read the cars.txt file, and store the data (field values) in objects of Car class. The complete code snippet looks as below:

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

public class Car implements Serializable {
  private String make;
  private int year;
  private static final long serialVersionUID = 1L;

  public Car(String make, int year) {
    this.make = make;
    this.year = year;
  }

  public String toString(){
    return String.format("Car make is: %s, Car year is: %d", this.make, this.year);
  }

  public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
    Car toyota = new Car("Toyota", 2021);
    Car honda = new Car("Honda", 2020);

    FileOutputStream fileOutputStream = new FileOutputStream("cars.txt");
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
    // serialization
    objectOutputStream.writeObject(toyota);
    objectOutputStream.writeObject(honda);

    FileInputStream fileInputStream = new FileInputStream("cars.txt");
    ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
    // deserialization
    Car toyotaCopy = (Car) objectInputStream.readObject();
    Car hondaCopy = (Car) objectInputStream.readObject();

    boolean isSameObject = toyotaCopy == toyota; // false
    System.out.println("Toyota (Copy) - "+toyotaCopy);
    System.out.println("Toyota (Original) - "+toyota);
    System.out.println("Is same object: "+ isSameObject);
  }
}

However, its important to note that the deserialized object is totally different from the serialized object, i.e, they occupy different space in memory.

Stay tuned for part2, where we will discuss more nuances around this topic.