Home/Learn/Java A–Z/Serialization

Serialization

Intermediate
I/O and Networking

Java serialization converts objects to byte streams for persistence or network transfer. Understanding its pitfalls is critical for secure, maintainable code.

Overview

Java serialization (java.io.Serializable) converts object graphs to byte sequences via ObjectOutputStream and restores them with ObjectInputStream. While convenient, serialization has significant drawbacks: it is a security attack surface, couples implementation details, and is slow. Modern alternatives include JSON (Jackson/Gson), protocol buffers, or records with explicit mapping. Understanding serialization is still important because many legacy systems and Java standard classes use it.

Basic Serialization

A class must implement Serializable (a marker interface) to be serialized. All non-transient instance fields are included. The serialVersionUID field provides version compatibility — if it changes, deserialization of old data fails with InvalidClassException.

static and transient fields are excluded from serialization.

Serialization.java
import java.io.*;

public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;
    private transient String password; // excluded

    public User(String name, int age, String password) {
        this.name = name;
        this.age = age;
        this.password = password;
    }
    // getters...
}

// Serialize
try (ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("user.ser"))) {
    oos.writeObject(new User("Alice", 30, "secret"));
}

// Deserialize
try (ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("user.ser"))) {
    User user = (User) ois.readObject();
    System.out.println(user.getName()); // Alice
    System.out.println(user.getPassword()); // null (transient)
}

Custom Serialization

Override writeObject and readObject to customize serialization. This lets you encrypt sensitive fields, validate data on deserialization, or handle version migrations.

readResolve() lets you control what object is returned after deserialization — used by Singletons and Enum-like patterns.

CustomSerialization.java
private void writeObject(ObjectOutputStream oos)
        throws IOException {
    oos.defaultWriteObject();
    // encrypt and write sensitive field manually
    oos.writeObject(encrypt(this.sensitiveData));
}

private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    this.sensitiveData = decrypt((String) ois.readObject());
    // validation
    if (this.age < 0) throw new InvalidObjectException("Bad age");
}

// Singleton preservation
private Object readResolve() {
    return INSTANCE; // always return the singleton
}

Alternatives to Java Serialization

Java serialization is not recommended for new code. Prefer JSON (Jackson), XML, or Protocol Buffers for interoperability; records or DTO classes with explicit mapping for type safety.

Jackson is the most popular alternative. If you must use serialization, use ObjectInputFilter (Java 9+) to whitelist allowed classes and prevent deserialization attacks.

JsonAlternative.java
// Jackson JSON (preferred alternative)
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
// Serialize to JSON string
String json = mapper.writeValueAsString(user);
// {"name":"Alice","age":30}

// Deserialize from JSON
User restored = mapper.readValue(json, User.class);

// Java 9+ deserialization filter (security)
ObjectInputFilter filter = ObjectInputFilter.Config
    .createFilter("com.example.*;java.lang.*;!*");
ObjectInputStream ois = new ObjectInputStream(fis);
ois.setObjectInputFilter(filter);

Key Points to Remember

  • Implement Serializable to enable serialization; add serialVersionUID for version stability.
  • transient fields are excluded; static fields are never serialized.
  • Override writeObject/readObject for custom serialization logic.
  • readResolve() controls what instance is returned after deserialization (used by Singletons).
  • Prefer JSON/Protobuf over Java serialization for new code — it is a security risk without ObjectInputFilter.

Practice Serialization in the Playground

Run and modify code directly in your browser - no setup needed.

Interview Questions

Sign in to ask Aria
1

What is serialVersionUID and what happens if it does not match during deserialization?

EasyTCS
2

Why is Java deserialization a security vulnerability?

MediumAmazon
3

What is the purpose of the transient keyword?

EasyGoogle
4

How would you prevent a Singleton from being duplicated via deserialization?

HardMicrosoft
5

What is ObjectInputFilter and why was it introduced?

HardOracle

Ask Aria about Serialization

Your personal AI tutor — ask anything about this concept