Вопрос-ответ

Implementing Singleton with an Enum (in Java)

Реализация синглтона с перечислением (в Java)

Я читал, что это можно реализовать Singleton в Java с помощью Enum такого как:

public enum MySingleton {
INSTANCE;
}

Но как работает вышеописанное? В частности, должен быть создан экземпляр Object. Здесь, как создается экземпляр MySingleton? Кто делает new MySingleton()?

Переведено автоматически
Ответ 1

Это,

public enum MySingleton {
INSTANCE;
}

имеет неявный пустой конструктор. Вместо этого сделайте его явным,

public enum MySingleton {
INSTANCE;
private MySingleton() {
System.out.println("Here");
}
}

Если затем вы добавили другой класс с main() методом, подобным

public static void main(String[] args) {
System.out.println(MySingleton.INSTANCE);
}

Вы увидите

Here
INSTANCE

enum поля являются константами времени компиляции, но они являются экземплярами своего enum типа. И они создаются, когда на тип enum ссылаются в первый раз.

Ответ 2

enum Тип - это особый тип class.

Ваш enum фактически будет скомпилирован во что-то вроде

public final class MySingleton {
public final static MySingleton INSTANCE = new MySingleton();
private MySingleton(){}
}

При первом обращении к вашему коду INSTANCEкласс MySingleton будет загружен и инициализирован JVM. Этот процесс инициализирует static поле выше один раз (лениво).

Ответ 3

В этой книге по рекомендациям по Java Джошуа Блоха вы можете найти объяснение, почему вы должны применять свойство Singleton с помощью частного конструктора или типа Enum. Глава довольно длинная, поэтому ее следует кратко изложить:

Превращение класса в Singleton может затруднить тестирование его клиентов, поскольку невозможно заменить singleton макетной реализацией, если он не реализует интерфейс, который служит его типом. Рекомендуемый подход заключается в реализации Singletons простым созданием типа enum с одним элементом:

// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}

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


Хотя этот подход еще не получил широкого распространения, одноэлементный тип enum является лучшим способом реализации синглтона.


Ответ 4

Как и все экземпляры enum, Java создает экземпляр каждого объекта при загрузке класса с некоторой гарантией того, что его экземпляр создается ровно один раз для JVM. Думайте о INSTANCE объявлении как о общедоступном статическом конечном поле: Java создаст экземпляр объекта при первом обращении к классу.

Экземпляры создаются во время статической инициализации, которая определена в Спецификации языка Java, раздел 12.4.

Как бы то ни было, Джошуа Блох подробно описывает этот шаблон в пункте 3 Effective Java Second Edition.

java enums