Можно ли сделать абстрактный класс синглтоном
Что проверяют
Различаете ли вы «нельзя создать экземпляр» и «экземпляр один», и понимаете ли, что синглтон это про жизненный цикл, а не про модификатор класса. Заодно смотрят на потокобезопасность и на то, кто в Java-проекте обычно управляет единственностью.
Как отвечать
Начните с формальной части: абстрактный класс инстанцировать нельзя, поэтому синглтоном становится не он, а его конкретный наследник. Статическая точка доступа в базовом классе, отдающая единственный экземпляр подкласса, технически соберётся, но это плохой дизайн: родитель начинает знать про потомка, а статическое поле в иерархии одно на всех, и второму наследнику своего экземпляра уже не достанется.
Как делают нормально:
- единственность объявляют у конкретного класса, абстрактный остаётся просто базой;
- для ленивой и потокобезопасной инициализации берут вложенный класс-держатель: JVM гарантирует однократную инициализацию класса, синхронизация не нужна;
enumиз одного элемента даёт защиту от сериализации и рефлексии бесплатно;- в приложении на Spring это обычно не пишут руками: бин по умолчанию и так один на контейнер, а абстрактный класс спокойно живёт как базовый тип.
public final class Registry {
private Registry() {}
private static final class Holder {
static final Registry INSTANCE = new Registry();
}
public static Registry get() { return Holder.INSTANCE; }
}Где спотыкаются
Первое: пишут проверку if (instance == null) без синхронизации и называют это ленивой инициализацией. Два потока зайдут одновременно и получат два объекта, то есть гарантии нет вовсе. Двойная проверка работает только с полем volatile.
Второе: говорят «один на JVM» про бин Spring. Scope singleton означает один на контейнер, и при нескольких контекстах, а в тестах это обычное дело, экземпляров окажется несколько.
Третье: не называют цену. Статическое состояние переживает тесты и течёт между ними, подменить его заглушкой трудно, а наследование от синглтона ломает сам контракт: у подкласса свой конструктор, и единственность расползается.