Serialization and Deserialization in Java

Naveen AnamaneniUpdated · 4 min read

Serialization in Java is the process of converting an object into a sequence of bytes, so it can be saved to a file, stored in a database or sent over a network. Deserialization is the reverse: rebuilding the object from those bytes. Java's built-in serialization uses ObjectOutputStream.writeObject and ObjectInputStream.readObject (introduced in "ObjectInputStream and ObjectOutputStream"), and works for classes that implement the Serializable interface. In this lesson, you will learn how the process works and what it saves.

How It Works

writeObject turns an object graph into bytes; readObject builds a new copy

When an object is serialized, Java writes:

  • A class description: the class name, its serialVersionUID, and the names and types of its fields.
  • The values of all non-static, non-transient fields.
  • Every object referenced by those fields, and so on, so the whole object graph is saved.

When it is deserialized, Java creates a new object without calling the class's constructor, and fills in the saved field values.

Example: Saving and Restoring an Object Graph

Let's see an example where a student refers to an address.

SerializeDemo.java▶ Try it
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
public class SerializeDemo {
    static class Address implements Serializable {
        String city;
        Address(String city) { this.city = city; }
    }
 
    static class Student implements Serializable {
        String name;
        int marks;
        Address address;
 
        Student(String name, int marks, Address address) {
            this.name = name;
            this.marks = marks;
            this.address = address;
            System.out.println("Constructor called for " + name);
        }
    }
 
    public static void main(String[] args)
            throws IOException, ClassNotFoundException {
        Student original = new Student("Navika", 91, new Address("Pune"));
 
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        try (ObjectOutputStream out = new ObjectOutputStream(bytes)) {
            out.writeObject(original);
        }
        System.out.println("Serialized into " + bytes.size() + " bytes");
 
        try (ObjectInputStream in = new ObjectInputStream(
                new ByteArrayInputStream(bytes.toByteArray()))) {
            Student copy = (Student) in.readObject();
            System.out.println("Restored: " + copy.name + ", " + copy.marks
                + ", " + copy.address.city);
            System.out.println("Same object? " + (copy == original));
        }
    }
}
Output
Constructor called for Navika
Serialized into 184 bytes
Restored: Navika, 91, Pune
Same object? false

Explanation: writeObject saved the student and the address it refers to. readObject rebuilt both as new objects; notice that the constructor message appeared only once, when the original was created, because deserialization doesn't call the constructor. The copy has the same values but is a different object.

Uses of Serialization

UseExample
Saving stateStoring a game's progress to a file
CachingKeeping computed objects on disk between runs
Sending objectsOlder remote technologies such as RMI
Deep copiesCopying an object graph by serializing and deserializing it

Common Mistakes

Expecting the constructor to run during deserialization. It doesn't; fields are filled in directly.

Forgetting that referenced objects must also be serializable. One non-serializable field object makes the whole write fail.

Expecting static fields to be saved. They belong to the class, not the object.

Interview Corner

What is serialization in Java?

Serialization converts an object, together with all the objects reachable from it, into a byte stream that records the class description and the values of its non-static, non-transient fields; it's done with ObjectOutputStream.writeObject for classes implementing Serializable. Deserialization, with ObjectInputStream.readObject, reads that stream and creates new objects with the same state, without calling the serializable class's constructor. It's used to persist objects, cache them, send them over a network, or deep-copy them.

Practice

  1. Easy: Serialize a Book object with a title and price to a file, then read it back and print it.
  2. Harder: Use serialization to make a deep copy of a List<Student> and show that changing the copy doesn't affect the original.

Quick check: Serialization

4 questions
1What does serialization produce?
2Is the constructor called during deserialization?
3What happens to objects referenced by the serialized object?
4Are static fields saved?

Key Takeaways

Was this tutorial helpful?

Lesson 370 of 482