Ich habe gelesen, dass es möglich ist, Singleton
in Java Folgendes zu implementieren Enum
:
public enum MySingleton {
INSTANCE;
}
Aber wie funktioniert das oben genannte? Insbesondere muss ein Object
instanziiert werden. Wie wird hier MySingleton
instanziiert? Wer macht new MySingleton()
?
java
design-patterns
enums
singleton
Anand
quelle
quelle
INSTANCE
ist das gleiche wiepublic static final MySingleton INSTANCE = new MySingleton();
.Antworten:
Dies,
hat einen impliziten leeren Konstruktor. Machen Sie es stattdessen explizit,
Wenn Sie dann eine weitere Klasse mit einer
main()
Methode wie hinzugefügt habenDu würdest sehen
enum
Felder sind Kompilierungszeitkonstanten, aber sie sind Instanzen ihresenum
Typs. Und sie werden erstellt, wenn der Aufzählungstyp zum ersten Mal referenziert wird .quelle
private
Modifikator hat für einenenum
Konstruktor keine Bedeutung und ist vollständig redundant.Ein
enum
Typ ist ein spezieller Typ vonclass
.Ihr
enum
Wille wird tatsächlich zu so etwas kompiliertWenn Ihr Code zum ersten Mal aufgerufen wird
INSTANCE
, wird die KlasseMySingleton
von der JVM geladen und initialisiert. Dieser Vorgang initialisiert dasstatic
obige Feld einmal (träge).quelle
public enum MySingleton { INSTANCE,INSTANCE1; }
und dann werdenSystem.out.println(MySingleton.INSTANCE.hashCode()); System.out.println(MySingleton.INSTANCE1.hashCode());
verschiedene Hashcodes gedruckt. Bedeutet dies, dass zwei Objekte von MySingleton erstellt werden?enum
.In diesem Java Best Practices-Buch von Joshua Bloch finden Sie Erklärungen, warum Sie die Singleton-Eigenschaft mit einem privaten Konstruktor oder einem Enum-Typ erzwingen sollten. Das Kapitel ist ziemlich lang, daher fasst es zusammen:
Wenn Sie eine Klasse zu einem Singleton machen, kann es schwierig sein, ihre Clients zu testen, da es unmöglich ist, einen Singleton durch eine Scheinimplementierung zu ersetzen, wenn nicht eine Schnittstelle implementiert wird, die als Typ dient. Der empfohlene Ansatz besteht darin, Singletons zu implementieren, indem einfach ein Aufzählungstyp mit einem Element erstellt wird:
Dieser Ansatz ist funktional äquivalent zum Public-Field-Ansatz, mit der Ausnahme, dass er präziser ist, die Serialisierungsmaschinerie kostenlos zur Verfügung stellt und eine ironclad-Garantie gegen Mehrfachinstanziierung bietet, selbst angesichts ausgefeilter Serialisierungs- oder Reflexionsangriffe.
quelle
Wie alle Enum-Instanzen instanziiert Java jedes Objekt, wenn die Klasse geladen wird, mit der Garantie, dass es genau einmal pro JVM instanziiert wird . Stellen Sie sich die
INSTANCE
Deklaration als ein öffentliches statisches Endfeld vor: Java instanziiert das Objekt, wenn die Klasse zum ersten Mal referenziert wird.Die Instanzen werden während der statischen Initialisierung erstellt, die in der Java-Sprachspezifikation, Abschnitt 12.4 definiert ist .
Für das, was es wert ist, beschreibt Joshua Bloch dieses Muster ausführlich als Punkt 3 der Effective Java Second Edition .
quelle
Da es bei Singleton Pattern darum geht, einen privaten Konstruktor zu haben und eine Methode zur Steuerung der Instanziierungen
getInstance
aufzurufen (wie einige ), haben wir in Enums bereits einen impliziten privaten Konstruktor.Ich weiß nicht genau, wie die JVM oder ein Container die Instanzen von uns steuert
Enums
, aber es scheint, dass sie bereits ein implizites verwendenSingleton Pattern
. Der Unterschied ist, dass wir nicht a nennen , sonderngetInstance
nur Enum.quelle
Wie bereits erwähnt, ist eine Aufzählung eine Java-Klasse mit der besonderen Bedingung, dass ihre Definition mit mindestens einer "Aufzählungskonstante" beginnen muss.
Abgesehen davon, dass Aufzählungen nicht erweitert oder zum Erweitern anderer Klassen verwendet werden können, ist eine Aufzählung eine Klasse wie jede andere Klasse, und Sie verwenden sie, indem Sie Methoden unterhalb der Konstantendefinitionen hinzufügen:
Sie greifen auf die folgenden Methoden des Singletons zu:
Bei der Verwendung einer Aufzählung anstelle einer Klasse geht es, wie in anderen Antworten erwähnt, hauptsächlich um eine thread-sichere Instanziierung des Singletons und die Garantie, dass es sich immer nur um eine Kopie handelt.
Und vielleicht am wichtigsten ist, dass dieses Verhalten durch die JVM selbst und die Java-Spezifikation garantiert wird.
Hier ist ein Abschnitt aus der Java-Spezifikation, wie mehrere Instanzen einer Enum-Instanz verhindert werden:
Bemerkenswert ist, dass nach der Instanziierung alle Thread-Sicherheitsbedenken wie in jeder anderen Klasse mit dem synchronisierten Schlüsselwort usw. behandelt werden müssen.
quelle