Gymterview
middle

В чем проблема сериализации Singleton?

При десериализации JVM создаёт новый экземпляр объекта, минуя приватный конструктор, что нарушает контракт Singleton — в системе оказывается два экземпляра вместо одного.

Пример
Singleton original = Singleton.getInstance();

// Сериализация → десериализация
Singleton deserialized = (Singleton) ois.readObject();

System.out.println(original == deserialized); // false — два экземпляра!

Решения

1. Метод readResolve — возвращает существующий экземпляр вместо десериализованного:

Пример
public class Singleton implements Serializable {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() { return INSTANCE; }

    private Object readResolve() throws ObjectStreamException {
        return INSTANCE; // Вместо нового объекта возвращаем существующий
    }
}

2. enum-Singleton — рекомендуемый подход, JVM гарантирует единственность:

Пример
public enum Singleton {
    INSTANCE;

    public void doSomething() { /* ... */ }
}

Enum-синглтон защищён от десериализации, рефлексии и клонирования «из коробки».

3. Запрет сериализации — если сериализация не нужна, выбросить NotSerializableException.

На собеседовании: назовите проблему (десериализация создаёт новый экземпляр), опишите решение через readResolve и порекомендуйте enum-подход как самый надёжный. Это один из самых популярных вопросов на стыке паттернов и сериализации.