Java.Serialization.What is the problem with Singleton serialization?

🧠 What’s a Singleton?

A Singleton ensures that a class has only one instance in the JVM:

public class Singleton implements Serializable {
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

✅ So when you do:

Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2); // true ✅

💥 Problem: Serialization Can Break It!

When you serialize and deserialize a Singleton:

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("singleton.ser"));
out.writeObject(Singleton.getInstance());
out.close();

ObjectInputStream in = new ObjectInputStream(new FileInputStream("singleton.ser"));
Singleton deserialized = (Singleton) in.readObject();

Now:

System.out.println(Singleton.getInstance() == deserialized); // ❌ false

❗ Why?

Because readObject() creates a new instance in memory.
So now you have two different instances — the singleton is broken.

✅ The Fix: Use readResolve()

To restore the singleton identity after deserialization, implement a method called readResolve():

private Object readResolve() throws ObjectStreamException {
    return getInstance(); // Return the original singleton
}

Java will automatically call this after readObject() — and replace the newly created object with the return value of readResolve().

🧪 Complete Fixed Example

public class Singleton implements Serializable {
    private static final long serialVersionUID = 1L;
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }

    private Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}

Now this works:

Singleton s1 = Singleton.getInstance();
Singleton s2 = deserializeFromFile();
System.out.println(s1 == s2); // ✅ true

🧵 TL;DR

ProblemExplanation
readObject() creates a new instanceSingleton broken
Resultsingleton != deserialized
FixAdd readResolve() to return the singleton
Best practiceAlways include readResolve() in serializable Singletons
This entry was posted in Без рубрики. Bookmark the permalink.

Leave a Reply

Your email address will not be published.