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-подход как самый надёжный. Это один из самых популярных вопросов на стыке паттернов и сериализации.