All 15 I/O & NIO questions
More in I/O & NIO
Advertisement
Java › I/O & NIO

How would you implement object serialization using ObjectOutputStream/ObjectInputStream, and what does the Serializable marker interface and serialVersionUID actually do?

Intermediate

Answer

Implementing Serializable (a marker interface with no methods, simply signaling to the JVM's built-in serialization mechanism that instances of this class are eligible to be converted to/from a byte stream) enables ObjectOutputStream.writeObject()/ObjectInputStream.readObject() to automatically serialize an object's entire field graph (recursively including any referenced objects, which must ALSO be Serializable) to/from bytes -- serialVersionUID is an explicit version identifier embedded in the serialized form specifically to detect class-definition mismatches between the version that serialized an object and the version attempting to deserialize it (if omitted, the JVM computes one automatically based on the class's structure, which is fragile since even a seemingly harmless code change can alter the computed value, causing InvalidClassException for previously-serialized data), so explicitly declaring a stable serialVersionUID is strongly recommended for any class expected to be serialized/deserialized across different versions of its own code.
public class User implements Serializable {
    private static final long serialVersionUID = 1L;  // explicit, stable version identifier
    private String name;
    private transient String temporaryToken;  // 'transient' excludes this field from serialization entirely
}

try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
    out.writeObject(new User());
}
Real-world example A caching system serializing objects to disk for persistence across application restarts explicitly declares a stable serialVersionUID on its cached data classes, avoiding a scenario where an unrelated, minor code refactor (like adding a new method) would otherwise silently change the auto-computed UID and invalidate every previously-cached, still-perfectly-valid serialized object.

Common follow-ups: What does the transient keyword do, and why would you want to exclude a field from serialization?;Why has Java's built-in serialization mechanism come to be viewed with security skepticism in modern practice, and what alternatives are commonly preferred?