serialVersionUID Explained
Fast recall
Quick revision
Core answer
serialVersionUID identifies the serialized version of a class. Java compares the stream's UID with the local class UID and rejects a mismatch, but a matching UID does not by itself guarantee that every class change is compatible.Interview-ready guide
Interview answer
serialVersionUID is the version identifier used by Java native serialization for a serializable class. It is conventionally declared private static final long serialVersionUID = 1L;. The object stream stores a class descriptor containing the UID, and ObjectInputStream compares it with the UID of the local class during deserialization.
If the class name corresponds but the UIDs differ, deserialization normally throws InvalidClassException. When no explicit field is declared, Java computes a default UID from details of the class. That computed value is fragile because changes to constructors, members, modifiers, or compiler-generated details can change it even when the developer intended compatible evolution.
An explicit UID makes the compatibility decision deliberate. A team can retain it for changes allowed by serialization's evolution rules, such as adding an ordinary field that older streams do not contain; the new field receives its default value. The team should change the UID when it intentionally wants older serialized forms rejected.
For example, a Profile class can declare UID 7L and verify it with ObjectStreamClass.lookup(Profile.class).getSerialVersionUID(). Streams written with that descriptor expect a compatible local Profile version to use the same value.
A matching UID is necessary but not sufficient. Incompatible structural changes can still fail or restore misleading state, and retaining a UID cannot transform an arbitrary new design into the old class. It also provides no security, integrity, or schema migration. Use explicit UIDs for controlled legacy serialization, test old-to-new data across releases, and prefer an explicit versioned format for durable or cross-service contracts.
serialVersionUID Explained
Direct Answer
serialVersionUID identifies the serialized version of a class. Java compares the stream's UID with the local class UID and rejects a mismatch, but a matching UID does not by itself guarantee that every class change is compatible.
Deep Dive & Architecture
Deserialization first decides whether the stream's class descriptor can match the local class. The serialVersionUID is a version gate in that decision. A mismatch rejects the stream before ordinary field restoration. This prevents accidental interpretation by a class version that declared itself different, but it says nothing about the business meaning of restored values.
Java separately defines compatible and incompatible evolution. Adding a field is generally readable because an old stream has no value and the new field receives a default. Deleting a field means a newer reader ignores old data for it. Moving classes within the hierarchy or changing a field to an incompatible type can violate the contract even if a developer forces the same UID.
The generated default UID depends on structural class information. Seemingly unrelated edits or compiler details can therefore affect it, making accidental generation unsuitable for data expected to survive releases. An explicit declaration exposes the compatibility promise during review, but the number still needs a policy.
Treat each retained UID as an obligation to run compatibility fixtures. Read representative bytes from supported older releases, validate invariants, and reject or migrate versions outside the support window. For new durable data, a schema with an explicit format version usually makes evolution safer and more observable than Java class descriptors.
Code Example
import java.io.ObjectStreamClass;
import java.io.Serializable;
class SerialVersionExample {
static final class Profile implements Serializable {
private static final long serialVersionUID = 7L;
final String name;
Profile(String name) { this.name = name; }
}
public static void main(String[] args) {
long uid = ObjectStreamClass.lookup(Profile.class).getSerialVersionUID();
if (uid != 7L) throw new AssertionError(uid);
System.out.println(uid);
}
}
Check your understanding
Answer these without looking back at the article.
- What happens when the stream UID and local class UID differ?
- Why is a generated default serialVersionUID fragile?
- Does keeping the same UID make every class change compatible?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.