Backend Development 13 min read

Understanding serialVersionUID and Java Serialization Mechanism

This article explains how Java's serialization mechanism uses serialVersionUID to ensure class version compatibility, demonstrates default and explicit UID generation, shows code examples for serialization and deserialization, and explores various scenarios including field changes, static variables, inheritance, and the transient keyword.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding serialVersionUID and Java Serialization Mechanism

serialVersionUID is used by Java's serialization mechanism to verify version compatibility; during deserialization the JVM compares the UID in the byte stream with the local class's UID and proceeds only if they match.

The serialization process writes the class's serialVersionUID to the file, and deserialization checks this value to determine if the class versions are compatible.

There are two ways to generate serialVersionUID:

Default value, e.g., private static final long serialVersionUID = 1L;

Explicitly generated 64‑bit hash based on class name, members, etc., e.g., private static final long serialVersionUID = xxxxL;

If a class implements Serializable without defining serialVersionUID, Eclipse can warn and offer to generate one.

When a class does not define serialVersionUID, the compiler generates one automatically; minor changes like whitespace do not affect it.

Explicitly defining serialVersionUID ensures compatibility across versions when the class evolves.

1) Serializable Entity Class

package com.sf.code.serial;

import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 123456789L;
    public int id;
    public String name;

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

    public String toString() {
        return "Person: " + id + " " + name;
    }
}

2) Serialization Code

package com.sf.code.serial;

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

public class SerialTest {
    public static void main(String[] args) throws IOException {
        Person person = new Person(1234, "wang");
        System.out.println("Person Serial" + person);
        FileOutputStream fos = new FileOutputStream("Person.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(person);
        oos.flush();
        oos.close();
    }
}

3) Deserialization Code

package com.sf.code.serial;

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

public class DeserialTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person person;
        FileInputStream fis = new FileInputStream("Person.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        person = (Person) ois.readObject();
        ois.close();
        System.out.println("Person Deserial" + person);
    }
}

Scenario 1: Different serialVersionUID values on A and B sides cause java.io.InvalidClassException during deserialization.

Exception in thread "main" java.io.InvalidClassException: com.sf.code.serial.Person; local class incompatible: stream classdesc serialVersionUID = 1234567890, local class serialVersionUID = 123456789
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:621)
    ...

Scenario 2: When UIDs match but A adds a field (e.g., age ) and B does not, the added field is ignored during deserialization.

Scenario 3: When B removes a field while UIDs match, the missing field's value is lost after deserialization.

Scenario 4: When B adds a new field while UIDs match, the new field receives its default value (e.g., 0 for int) after deserialization.

Static Variable Serialization

Static variables are not serialized; changing a static variable after serialization is reflected when the object is deserialized, as demonstrated by the output 10 instead of the original 5 .

Superclass Serialization and Transient Keyword

If a subclass implements Serializable but its superclass does not, the superclass is not serialized; during deserialization the JVM invokes the superclass's no‑arg constructor, so its fields take default values unless initialized there.

The transient keyword prevents a field from being serialized; after deserialization such fields revert to their default values.

Alternative to transient : place non‑serializable fields in a non‑serializable superclass, so they are naturally omitted during serialization.

Source code of ObjectStreamClass.writeNonProxy shows that the serialVersionUID is written explicitly to the stream.

javaserializationSerializableserialVersionUIDObjectInputStreamObjectOutputStream
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.