Java Object Serialization: Serializable, serialVersionUID & Transient

In Java, Serialization transforms the state of an active object into a byte stream. This byte stream can be written to a disk file, cached in Redis, or transmitted across network sockets (e.g., in RMI, microservices, or distributed clustering). Deserialization performs the inverse operation: reconstituting the live object on the JVM Heap.

Marker Interface Notice

java.io.Serializable is a Marker Interface (it contains zero methods and zero fields). It simply signals the JVM that instances of this class are permissible to serialize.

1. Creating a Serializable Class

import java.io.Serializable;

public class Employee implements Serializable {
    // Explicit serialVersionUID ensures version compatibility
    private static final long serialVersionUID = 1L;
    
    private int id;
    private String name;
    private double salary;
    
    // transient fields are IGNORED during serialization
    private transient String passwordHash;
    
    public Employee(int id, String name, double salary, String passwordHash) {
        this.id = id;
        this.name = name;
        this.salary = salary;
        this.passwordHash = passwordHash;
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + "', salary=" + salary + 
               ", passwordHash='" + passwordHash + "'}";
    }
}

2. Serializing with ObjectOutputStream

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

public class SerializeDemo {
    public static void main(String[] args) {
        Employee emp = new Employee(101, "Aarav Sharma", 85000.0, "secret#SaltedPass2026");
        
        try (FileOutputStream fileOut = new FileOutputStream("employee.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            
            out.writeObject(emp);
            System.out.println("Employee object serialized successfully to employee.ser");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. Deserializing with ObjectInputStream

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

public class DeserializeDemo {
    public static void main(String[] args) {
        try (FileInputStream fileIn = new FileInputStream("employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            
            // Read object and cast back to Employee
            Employee emp = (Employee) in.readObject();
            System.out.println("Object Deserialized successfully:");
            System.out.println(emp);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
Console Output Trace
Object Deserialized successfully:
Employee{id=101, name='Aarav Sharma', salary=85000.0, passwordHash='null'}

Notice that passwordHash is null because it was marked transient!

What is serialVersionUID and Why Declare It?

If you do not explicitly define a serialVersionUID, the Java compiler automatically generates one based on class member signatures, interfaces, and methods. However, if you later add even a single comment or harmless method, the compiler's auto-generated hash changes, causing existing stored files to fail with:

java.io.InvalidClassException: Employee; local class incompatible: 
stream classdesc serialVersionUID = -248293..., local class serialVersionUID = 718392...

Best Practice: Always declare private static final long serialVersionUID = 1L; explicitly in every serializable class.

Rules of Java Serialization

  • Static Fields: Static variables belong to the Class, not individual instances. Hence, static fields are never serialized.
  • Object Graphs: If a serializable object references another object, the referenced object must also implement Serializable, otherwise a NotSerializableException is thrown.
  • Constructors: During deserialization, the constructor of the serializable class is NOT executed. Only the no-arg constructor of the nearest non-serializable superclass is called.
BCA / University Exam Corner
  • Viva Question: Can we serialize a class if its superclass does not implement Serializable?
    Answer: Yes, a subclass can implement Serializable even if its superclass does not. However, the superclass must have a visible no-argument constructor so the JVM can initialize inherited fields during deserialization.
  • Distinction Question: What is the difference between Serializable and Externalizable?
    Answer: Serializable is a marker interface where serialization logic is automated by the JVM. Externalizable extends Serializable and mandates the implementation of two methods: writeExternal() and readExternal(), giving complete programmer control over serialization format.

Frequently Asked Questions (FAQ)

Q1. What is Serialization and Deserialization in Java?
Serialization is the process of converting an in-memory Java object into a portable stream of bytes so it can be saved to a file, database, or transmitted across a network socket. Deserialization is the reverse process: reconstructing the exact live Java object in memory from the byte stream.
Q2. Why is serialVersionUID crucial in a Serializable class?
serialVersionUID is a universal version identifier for a Serializable class. When deserializing an object, the JVM compares the serialized object UID with the current local class UID. If they do not match (e.g., if a field was added or altered), deserialization fails with an InvalidClassException.
Q3. What is the purpose of the transient keyword?
The transient keyword tells the JVM serialization engine to skip a specific field during serialization. It is used to protect sensitive data (such as passwords, credit card numbers) or non-serializable references (such as database connections or thread handles). Transient fields deserialize to their default values (null, 0, or false).

Explore Related Java Tutorials

Accelerate your Java mastery by studying these tightly connected core tutorials:

File I/O Streams →

Byte stream foundations for Object streams.

JVM Memory Architecture →

How objects reside in Heap memory.

Access Modifiers & Transient →

Understanding special Java field modifiers.

Try-with-Resources →

Closing ObjectOutputStream safely.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!