Enum Singleton

Модуль 1. Java Syntax
20 уровень , 2 лекция
Открыта

Недавно мы с тобой разбирались, что такое Singleton, как его реализовать на Java и для чего он нужен. Но что если я тебе расскажу, что у Java уже есть свой синглтон из коробки? Интересно? Тогда давай разбираться.

Вероятно, ты уже знаешь о классе enum. У него есть особенность, о которой тебе стоит знать. Дело в том, что enum является реализацией синглтона. Такой вариант почти аналогичен подходу с public полем.

Singleton as enum:


public enum Device {   
    PRINTER	
} 
    

Public variable singleton:


public class Printer {   
    public static final Printer PRINTER = new Printer();   
    private Printer() {
    }
//…
}
    

В случае с публичным полем вариант с enum более компактен — не нужно писать свою реализацию. И что самое важное — у енамов нет проблем с сериализацией.

Сериализация здесь работает не так, как для для обычных объектов: сериализируется только значение имени енама. При десериализации метод используется с десериализованным именем, чтобы получить экземпляр. Также enum позволяет защитить себя от рефлексивных атак.

Больше о Reflection ты узнаешь из лекций второго модуля, в теме Reflection API.

Java представляет запрет на инстанциирование енамов, и это закодировано в реализации метода newInstance класса Constructor, который часто вызывают при создании объектов через рефлексию.

Часть кода из Constructor.newInstance для создания enum:


if ((clazz.getModifiers() & Modifier.ENUM) != 0)
    throw new IllegalArgumentException("Cannot reflectively create enum objects");
    

Из минусов создания Singleton через enum стоит назвать:

  • Отсутствие ленивой инициализации, так как объект создается сразу, и нельзя сделать отложенную инициализацию.

  • Невозможно расширять другие классы. То есть использовать enum как Singleton в случаях, когда нужно наследоваться от другого класса, не получится. В таких случаях нужно обращаться к уже знакомым нам вариантам реализации через статический метод или публичную переменную.

  • Используя enum как синглтон, ты можешь использовать только одно поле в enum классе.


public enum Device extends Electricity { 
    PRINTER 
}
    

Такой код выдаст нам ошибку компиляции:

No extends clause allowed for enum

Но если нам нужно реализовать интерфейс, нет проблем: enum-ы могут имплементировать интерфейсы:


public enum Device implements Electricity { 
    PRINTER 
}
    

Если тебе не нужно использовать наследование, лучше использовать реализацию Singleton через enum. Так советуем делать не только мы, но и сам Джошуа Блох.

Использование такой реализации дает тебе удобство, компактность, сериализацию из коробки, защиту от рефлексивных атак и уникальность, а это то, что нужно для хорошего Синглтона!

20
Задача
Java Syntax Pro, 20 уровень, 2 лекция
Недоступна
Создаем главный класс игры
Чтобы запустить игру, создай класс FirstGame и унаследуй его от класса Game. Также переопредели метод "игрового движка" - initialize(). Попробуй запустить на выполнение класс FirstGame и посмотри, что получилось.
20
Задача
Java Syntax Pro, 20 уровень, 2 лекция
Недоступна
Отображаем корабль
Попробуем отрисовать простую фигуру на игровом поле. Тебе нужно переопределить метод initialize() класса Game, и в этом методе задать размер игрового поля (5х7) с помощью метода setScreenSize(int, int). Также нужно вызвать метод showShip(), который отрисовывает корабль.
20
Задача
Java Syntax Pro, 20 уровень, 2 лекция
Недоступна
Простая программа
А сейчас научимся раскрашивать клетки и выводить в них текст. Необходимо вывести слово JAVARUSH. 1. Для начала переопредели метод initialize() класса Game, в котором задай размер поля (8x3). 2. Далее с помощью метода setCellValueEx(int, int, Color, String) выведи слово в одну линию. Этот метод раскр
Комментарии (27)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Руслан Уровень 46
18 августа 2025
Надо через конструктор в enum задачку решать
Булат Уровень 109
24 июля 2024
не понял задачу, но помогла вот эта статья( пример 5 Реализация) https://vertex-academy.com/tutorials/ru/pattern-singleton-realizacii/
Олег Уровень 106 Expert
31 мая 2024
А почему выводится сверху, а не снизу, например?
Александр Уровень 66
1 июля 2024
Пните когда будет ответ. Аналогичный вопрос.
Farhad Уровень 1
27 июля 2024
Если рассматривать ваш вопрос, то возникнет встречный: а как объект может использоваться до своего физического создания? Сначала создается и инициализируется объект, а затем он используется. Конструктор вызывается для инициализации состояния объекта на момент создания до использования его (объекта) где-либо еще в коде. Соответственно, строка "создание экземпляра..." будет выведена первой. Здесь очень важно рассматривать константу перечисления как конечный объект, который имеет все те же характеристики, что и обычные - неконечные. Здесь про порядок инициализации объектов
Farhad Уровень 1
27 июля 2024
пнул
Сергей Титов Уровень 1
28 марта 2024
Вообще не к месту статья. Вот это: Java представляет запрет на инстанциирование енамов, и это закодировано в реализации метода newInstance класса Constructor, который часто вызывают при создании объектов через рефлексию. Часть кода из Constructor.newInstance для создания enum: if ((clazz.getModifiers() & Modifier.ENUM) != 0) throw new IllegalArgumentException("Cannot reflectively create enum objects"); вообще прям понятно, слов нет. Как раз про это всё станет известно сильно потом, зачем оно сейчас?
Farhad Уровень 1
27 июля 2024
Если коротко: рефлексия используется для извлечения данных о программе во время выполнения. Защита от этого механизма предотвращает создание объекта enum'a с помощью его конструктора. Будет странно, если в программе будет два одинаковых объекта enum, не так ли? Это противоречит самой сути данного типа данных. А вот с классами, насколько мне известно, такой трюк вполне можно провернуть =)
Andrzej Уровень 32 Expert
22 ноября 2023
Если тебе не нужно использовать наследование, лучше использовать реализацию Singleton через enum. Так советуем делать не только мы, но и сам Джошуа Блох. Ссылка не работает к сожалению, если кто-то знает на что она должна вести, поделитесь пожалуйста.
Vitalii Уровень 13 Expert
27 августа 2023
Что это? Зачем это здесь?
jvatechs Уровень 111 Expert
4 декабря 2022
https://habr.com/ru/post/129494/ Немного доходчиво
java Уровень 108 Expert
16 сентября 2022
Задача легкая если знать что в enum можно создавать конструктор
Пахопол Юлия Уровень 51 Expert
18 августа 2022
ниче не понятно, но оч интересно
Екатерина Уровень 70 Expert
8 августа 2022
непоняяятно, но пример оч любопытный,