← Back to Home

Serialization

Serialization in Java is the process of converting an object into a byte stream so that it can be stored (file, DB) or transmitted (network) and later reconstructed back into the same object (deserialization).

This is a high-frequency interview topic, especially around marker interfaces, serialVersionUID, and transient fields.

What Is Serialization?

  • Converts object → byte stream
  • Enables persistence and network transfer
  • Reverse process is deserialization
  • Implemented using Object Streams

Why Serialization Is Needed

  • Save object state to file
  • Send objects over network (RMI, sockets)
  • Cache objects
  • Session replication (web apps)

Key Interfaces & Classes

Marker Interface

java.io.Serializable

  • ✔ No methods
  • ✔ Marks a class as serializable

Object Streams

  • ObjectOutputStream → serialize
  • ObjectInputStream → deserialize

Basic Serialization Example

Serializable Class

import java.io.Serializable;
class Employee implements Serializable {
    int id;
    String name;
    Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
          

Serialization (Object → File)

ObjectOutputStream oos =
    new ObjectOutputStream(new FileOutputStream("emp.ser"));
Employee e = new Employee(1, "Java");
oos.writeObject(e);
oos.close();
          

Deserialization (File → Object)

ObjectInputStream ois =
    new ObjectInputStream(new FileInputStream("emp.ser"));
Employee e = (Employee) ois.readObject();
ois.close();
✔ Object state restored
✔ New object created in memory
          

Important Rules of Serialization

  1. Class must implement Serializable
  2. All non-transient fields are serialized
  3. Static variables are NOT serialized
  4. Constructors are NOT called
  5. Parent class must be Serializable or have no-arg constructor

transient Keyword (Very Important)

Marks fields not to be serialized.

class User implements Serializable {
    String username;
    transient String password;
}
✔ password not stored
✔ Value becomes default (null) after deserialization
          

serialVersionUID (Interview Favorite)

Used for version control of serialized classes.

private static final long serialVersionUID = 1L;
          

Why Needed?

  • Ensures compatibility during deserialization
  • Prevents InvalidClassException
  • ✔ Always define explicitly
  • ✔ Best practice

What Happens If Class Changes?

Scenario Result
serialVersionUID unchanged Deserialization succeeds
serialVersionUID changed ❌ InvalidClassException
No UID defined JVM generates one

Serialization Process (Conceptual Flow)

Object
 ↓ writeObject()
Byte Stream
 ↓ readObject()
Object (New Instance)
          

Custom Serialization (Advanced)

Override default behavior:

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
}
private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
}
✔ Used for encryption, validation, custom logic
          

Serialization vs Externalization

Aspect Serializable Externalizable
Control Less Full
Methods None writeExternal, readExternal
Performance Slower Faster
Ease Easy Complex

Security Concerns (Real-World)

  • Serialized data can be tampered
  • Vulnerable to deserialization attacks
  • Avoid deserializing untrusted data
  • ✔ Use validation
  • ✔ Prefer JSON/XML for APIs

Common Beginner Mistakes

  • Forgetting to implement Serializable
  • Not defining serialVersionUID
  • Expecting static fields to serialize
  • Assuming constructors run
  • Serializing sensitive data without transient

Best Practices (Production-Grade)

  • Always define serialVersionUID
  • Use transient for sensitive fields
  • Avoid Java serialization for APIs
  • Prefer JSON (Jackson) or Protobuf
  • Validate deserialized objects

Interview-Ready Answers

Short Answer

Serialization converts an object into a byte stream for storage or transmission.

Detailed Answer

In Java, serialization is the process of converting an object into a byte stream using ObjectOutputStream so that it can be persisted or sent over a network. The class must implement Serializable, and deserialization reconstructs the object using ObjectInputStream. Fields marked transient are not serialized, and serialVersionUID ensures version compatibility.

Key Takeaway

Serialization = Object persistence & transport. Powerful but risky—use carefully, define serialVersionUID, and avoid for public APIs unless required.

Serialization Interview Cheat Sheet

1. Basic Serialization (Serializable)

import java.io.*;

class User implements Serializable {
    int id;
    String name;

    User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

class Demo {
    public static void main(String[] args) throws Exception {
        User u = new User(1, "Java");

        ObjectOutputStream oos =
            new ObjectOutputStream(new FileOutputStream("user.ser"));
        oos.writeObject(u);
        oos.close();
    }
}
          

2. Basic Deserialization

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        ObjectInputStream ois =
            new ObjectInputStream(new FileInputStream("user.ser"));

        User u = (User) ois.readObject();
        System.out.println(u.id + " " + u.name);
        ois.close();
    }
}
          

3. transient Keyword (Not Serialized)

import java.io.*;

class User implements Serializable {
    int id;
    transient String password;

    User(int id, String password) {
        this.id = id;
        this.password = password;
    }
}

// After deserialization
password → null
          

Interview Point: transient fields are ignored.

4. static Variables Are Not Serialized

import java.io.*;

class Demo implements Serializable {
    static int x = 10;
}
          

Explanation: static belongs to class, not object.

5. serialVersionUID (Very Important)

import java.io.*;

class User implements Serializable {
    private static final long serialVersionUID = 1L;
    int id;
}
          

Why:

  • Prevents InvalidClassException
  • Ensures version compatibility

6. Serialization Without serialVersionUID (Trap)

// JVM generates UID automatically
// Class change → deserialization fails
          

7. Parent Serializable, Child Not Serializable

import java.io.*;

class Parent implements Serializable {
    int x = 10;
}

class Child extends Parent {
    int y = 20;
}
          

Result: Child object can be serialized.

8. Parent Not Serializable, Child Serializable

import java.io.*;

class Parent {
    int x = 10;
}

class Child extends Parent implements Serializable {
    int y = 20;
}
          

Important:

  • Parent constructor must have no-arg constructor
  • Parent data is not serialized

9. Custom Serialization (writeObject / readObject)

import java.io.*;

class User implements Serializable {
    transient String password;
    int id;

    User(int id, String password) {
        this.id = id;
        this.password = password;
    }

    private void writeObject(ObjectOutputStream oos) throws Exception {
        oos.defaultWriteObject();
        oos.writeObject("ENC-" + password);
    }

    private void readObject(ObjectInputStream ois) throws Exception {
        ois.defaultReadObject();
        password = ((String) ois.readObject()).substring(4);
    }
}
          

10. Serialization with ArrayList

import java.io.*;
import java.util.*;

class Demo {
    public static void main(String[] args) throws Exception {
        ArrayList list = new ArrayList<>();
        list.add("Java");
        list.add("Selenium");

        ObjectOutputStream oos =
            new ObjectOutputStream(new FileOutputStream("list.ser"));
        oos.writeObject(list);
        oos.close();
    }
}
          

11. Deserializing ArrayList

import java.io.*;
import java.util.*;

class Demo {
    public static void main(String[] args) throws Exception {
        ObjectInputStream ois =
            new ObjectInputStream(new FileInputStream("list.ser"));

        ArrayList list =
            (ArrayList) ois.readObject();

        System.out.println(list);
        ois.close();
    }
}
          

12. Serialization of Multiple Objects

oos.writeObject(obj1);
oos.writeObject(obj2);

obj1 = ois.readObject();
obj2 = ois.readObject();

// Order matters
          

13. NotSerializableException (Common Interview Trap)

class A {
    int x = 10;
}

class B implements Serializable {
    A a = new A(); // ❌ A is not Serializable
}
          

Fix: class A implements Serializable {}

14. Serialization with try-with-resources

try (ObjectOutputStream oos =
         new ObjectOutputStream(new FileOutputStream("a.ser"))) {
    oos.writeObject(obj);
}
          

15. Serialization vs File Writing

  • FileWriter → text only
  • ObjectOutputStream → object graph

16. Deep Serialization (Object Graph)

class Order implements Serializable {
    User user; // user must be Serializable
}
          

Rule: All referenced objects must be serializable.

17. Marker Interface Concept

Serializable // no methods
          

Explanation: JVM uses it as a marker.

18. When NOT to Use Serialization

// Sensitive data
// Cross-language communication
// Large performance-critical systems
          

19. Real-World Use Cases

// Caching
// Session replication
// Deep copy of objects
          

20. Interview Summary – Serialization

implements Serializable

Key Points

  • Converts object → byte stream
  • Uses ObjectOutputStream / ObjectInputStream
  • transient & static not serialized
  • serialVersionUID is critical
  • All referenced objects must be serializable