605 Stimmen

Was sind enums und warum sind sie nützlich?

Heute habe ich einige Fragen auf dieser Website durchgesehen und eine Erwähnung eines enum im Singleton-Muster gefunden, das angeblich thread-sichere Vorteile für eine solche Lösung bietet.

Ich habe noch nie enums verwendet und programmiere seit mehr als ein paar Jahren in Java. Und anscheinend haben sie sich viel verändert. Jetzt unterstützen sie sogar vollständige OOP innerhalb sich selbst.

Warum und wofür sollte ich enums im täglichen Programmieren verwenden?

10 Stimmen

1 Stimmen

Sie können Enums nicht instanziieren, da diese einen privaten Konstruktor haben. Sie werden beim Starten der JVM instanziiert, also handelt es sich um Singletons. Enums sind nicht thread-sicher.

0 Stimmen

Ich stimme dafür, diese Frage zu schließen, weil dieses Meta das besagt: meta.stackoverflow.com/questions/429367/closing-consistency

2voto

Rahul Prajapat Punkte 35

Java ermöglicht es Ihnen, eine Variable auf nur wenige vordefinierte Werte zu beschränken - mit anderen Worten, ein Wert aus einer aufgezählten Liste. Die Verwendung von enums kann dazu beitragen, Fehler in Ihrem Code zu reduzieren. Hier ist ein Beispiel für enums außerhalb einer Klasse:

enums coffeesize{BIG , HUGE , OVERWHELMING }; 
// Dieses Semikolon ist optional.

Dies beschränkt coffeesize darauf, entweder BIG, HUGE oder OVERWHELMING als Variable zu haben.

2voto

BradB Punkte 11

In meiner Erfahrung habe ich gesehen, dass die Verwendung von Enums manchmal dazu führen kann, dass Systeme sehr schwer zu ändern sind. Wenn Sie ein Enum für eine Gruppe von domänenspezifischen Werten verwenden, die sich häufig ändern, und es viele andere Klassen und Komponenten gibt, die davon abhängen, sollten Sie in Betracht ziehen, kein Enum zu verwenden.

Zum Beispiel ein Handelssystem, das ein Enum für Märkte/Börsen verwendet. Es gibt viele Märkte da draußen und es ist fast sicher, dass es viele Teilsysteme geben wird, die auf diese Liste von Märkten zugreifen müssen. Jedes Mal, wenn Sie einen neuen Markt zu Ihrem System hinzufügen möchten, oder wenn Sie einen Markt entfernen möchten, ist es möglich, dass alles von Grund auf neu erstellt und veröffentlicht werden muss.

Ein besseres Beispiel wäre etwas wie ein Produktkategorietyp. Angenommen, Ihre Software verwaltet das Inventar für ein Kaufhaus. Es gibt viele Produktkategorien, und viele Gründe, warum sich diese Liste von Kategorien ändern könnte. Manager möchten vielleicht eine neue Produktlinie stocken, andere Produktlinien loswerden und möglicherweise die Kategorien von Zeit zu Zeit neu organisieren. Wenn Sie alle Ihre Systeme neu erstellen und bereitstellen müssen, einfach weil Benutzer eine Produktkategorie hinzufügen möchten, dann haben Sie etwas, das einfach und schnell sein sollte (das Hinzufügen einer Kategorie) sehr schwierig und langsam gemacht.

Im Endeffekt sind Enums gut, wenn die Daten, die Sie repräsentieren, im Laufe der Zeit sehr statisch sind und eine begrenzte Anzahl von Abhängigkeiten haben. Aber wenn die Daten sich häufig ändern und viele Abhängigkeiten bestehen, dann benötigen Sie etwas Dynamisches, das nicht zur Kompilierzeit überprüft wird (wie eine Datenbanktabelle).

2voto

Abhishek Bhandari Punkte 585

Enum? Warum sollte es verwendet werden? Ich denke, es wird eher verstanden, wenn du es verwenden wirst. Ich habe die gleiche Erfahrung.

Angenommen, du hast eine Datenbankoperation zum Erstellen, Löschen, Bearbeiten und Lesen.

Jetzt, wenn du ein enum als Operation erstellst:

public enum operation {
    create("1")
    delete("2")
    edit("3")
    read("4")

    // Du kannst hier auch Methoden haben
    public boolean isCreate() {
        return this.equals(create);
    }
    // Mehr Methoden wie die oben genannte können geschrieben werden

}

Nun kannst du etwas wie folgt deklarieren:

private operation currentOperation;

// Und weise ihm den Wert zu
currentOperation = operation.create

So kannst du es auf viele Arten verwenden. Es ist immer gut, ein enum für spezifische Dinge zu haben, da die Datenbankoperation im obigen Beispiel durch Überprüfen des currentOperation gesteuert werden kann. Man könnte vielleicht sagen, dass dies auch mit Variablen und Ganzzahlenwerten erreicht werden kann. Aber ich glaube, dass Enum sicherer ist und eher die Art eines Programmierers ist.

Noch etwas: Ich denke, jeder Programmierer liebt boolean, oder? Weil es nur zwei Werte, zwei spezifische Werte, speichern kann. Daher kann ein Enum als ähnliches Konzept betrachtet werden, wo ein Benutzer definiert, wie viele und welche Art von Werten es speichern wird, nur auf eine etwas andere Weise. :)

1voto

Nicolas Voron Punkte 2836

Zusätzlich zu @BradBs Antwort:

Das ist so wahr... Es ist seltsam, dass dies die einzige Antwort ist, die das erwähnt. Wenn Anfänger enums entdecken, nehmen sie das schnell als Zaubertrick für die Überprüfung von gültigen Bezeichnern durch den Compiler. Und wenn der Code für verteilte Systeme gedacht ist, weinen sie... einige Monate später. Die Aufrechterhaltung der Abwärtskompatibilität mit enums, die keine statische Liste von Werten enthalten, ist ein echtes Anliegen und Schmerz. Dies liegt daran, dass sich der Typ ändert, wenn Sie einem vorhandenen enum einen Wert hinzufügen (obwohl der Name gleich bleibt).

"Moment, das mag doch wie derselbe Typ aussehen, oder? Schließlich sind es Enums mit dem gleichen Namen – und sind Enums nicht einfach Ganzzahlen unter der Haube?" Aus diesen Gründen wird Ihr Compiler wahrscheinlich nicht den Gebrauch einer Definition des Typs selbst markieren, wenn er die andere erwartet hat. Aber tatsächlich handelt es sich (auf die wichtigsten Arten) um verschiedene Typen. Am wichtigsten ist, dass sie unterschiedliche Datenbereiche haben - Werte, die für den Typ akzeptabel sind. Durch das Hinzufügen eines Werts haben wir effektiv den Typ des Enums geändert und damit die Abwärtskompatibilität gebrochen.

Zusammenfassend: Verwenden Sie es, wenn Sie möchten, aber bitte überprüfen Sie, dass der verwendete Datenbereich eine endliche, bereits bekannt, feste Menge ist.

1voto

Oleg Poltoratskii Punkte 478

Das auf einem Enum basierende Singleton

eine moderne Betrachtung eines alten Problems

Dieser Ansatz implementiert das Singleton, indem er von der Garantie von Java Gebrauch macht, dass jeder Enum-Wert in einem Java-Programm nur einmal instanziiert wird und die Enum implizite Unterstützung für Thread-Sicherheit bietet. Da Java Enum-Werte global zugänglich sind, können sie als Singleton verwendet werden.

public enum Singleton {
    SINGLETON; 
    public void method() { }
}

Wie funktioniert das? Nun, Zeile zwei des Codes kann als etwas wie dieses betrachtet werden:

public final static Singleton SINGLETON = new Singleton(); 

Und wir erhalten das altbekannte früh initialisierte Singleton.

Denken Sie daran, dass Sie aufgrund dieser Enum jederzeit auf die Instanz über Singleton.SINGLETON zugreifen können:

Singleton s = Singleton.SINGLETON;

Vorteile

  • Um das Erstellen anderer Instanzen des Singletons während der Deserialisierung zu verhindern, verwenden Sie das auf einem Enum basierende Singleton, da die Serialisierung von Enum von der JVM übernommen wird. Enum-Serialisierung und Deserialisierung funktionieren anders als bei normalen Java-Objekten. Das einzige, was serialisiert wird, ist der Name des Enum-Werts. Während des Deserialisierungsprozesses wird die Methode valueOf des Enums mit dem deserialisierten Namen verwendet, um die gewünschte Instanz zu erhalten.

  • Das auf einem Enum basierende Singleton schützt sich vor Reflektionsangriffen. Der Enum-Typ erweitert tatsächlich die java Enum-Klasse. Der Grund, warum Reflektion nicht verwendet werden kann, um Objekte des Enum-Typs zu instanziieren, liegt daran, dass die Java-Spezifikation es verbietet und diese Regel in der Implementierung der newInstance-Methode der Constructor-Klasse codiert ist, die normalerweise zur Erstellung von Objekten über Reflektion verwendet wird:

    if ((clazz.getModifiers() & Modifier.ENUM) != 0) throw new IllegalArgumentException("Kann keine Enum-Objekte reflektiv erstellen");

  • Enum soll nicht geklont werden, da jeweils genau eine Instanz jedes Werts vorhanden sein muss.

  • Der lakonischste Code unter allen Singleton-Realisierungen.

Nachteile

  • Das auf einem Enum basierende Singleton erlaubt keine verzögerte Initialisierung.
  • Wenn Sie Ihr Design geändert und Ihr Singleton in einen Multiton umwandeln wollten, würde das Enum dies nicht erlauben. Das Multiton-Muster wird für die kontrollierte Erstellung mehrerer Instanzen verwendet, die es durch die Verwendung einer map verwaltet. Anstatt eine einzelne Instanz pro Anwendung (z. B. die java.lang.Runtime) zu haben, stellt das Multiton-Muster stattdessen eine einzelne Instanz pro Schlüssel sicher.
  • Enum erscheint nur in Java 5, so dass Sie es nicht in der vorherigen Version verwenden können.

Es gibt mehrere Realisierungen des Singleton-Musters, jede mit Vor- und Nachteilen.

  • Eager loading Singleton
  • Double-checked Locking Singleton
  • Initialisierung-über-Methode-Holder Idiom
  • Das auf einem Enum basierende Singleton

Eine ausführliche Beschreibung jeder von ihnen ist zu ausführlich, also habe ich einfach einen Link zu einem guten Artikel eingefügt - Alles, was Sie über Singleton wissen möchten

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X