Beim Programmieren stoßen wir häufig auf die Notwendigkeit, die Menge gültiger Werte für einen bestimmten Datentyp einzuschränken. So kann beispielsweise der Wochentag 7 verschiedene Werte haben, der Monat des Jahres 12 und die Jahreszeit 4. Um solche Probleme zu lösen, stellen viele statisch typisierte Programmiersprachen einen speziellen Datentyp bereit – Aufzählung ( Enum-Mitglieder sind Instanzen
Elemente
enum
). Die Aufzählung wurde in Java nicht sofort angezeigt. enum
Ab Version 1.5 wurde ein spezielles Sprachkonstrukt eingeführt. Bisher haben Programmierer andere Methoden zur Implementierung von Aufzählungen verwendet.
Enum-Konstrukt
Beginnen wir mit einem Beispiel. Beschreiben wirenum
den Datentyp zum Speichern der Saison mit:
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
Nun, ein einfaches Beispiel für seine Verwendung:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
Dadurch wird SUMMER auf der Konsole ausgegeben . Ich denke, dass das Beispiel offensichtlich ist und keiner Erklärung bedarf.
Enum ist eine Klasse
Durch die Deklarationenum
erstellen wir implizit eine von abgeleitete Klasse java.lang.Enum
. Herkömmlicherweise enum Season { ... }
entspricht die Konstruktion class Season extends java.lang.Enum { ... }
. Und obwohl der Compiler es uns nicht erlaubt, explizit von java.lang.Enum
uns zu erben, lässt sich die Vererbung dennoch leicht überprüfen, indem enum
man Folgendes verwendet reflection
:
System.out.println(Season.class.getSuperclass());
Folgendes wird auf der Konsole angezeigt:
class java.lang.Enum
Die eigentliche Vererbung wird für uns automatisch vom Java-Compiler durchgeführt. Als Nächstes vereinbaren wir, die vom Compiler zur Implementierung der Aufzählung erstellte Klasse als enum
-class und die möglichen Werte des Aufzählungstyps als enum
-a-Elemente aufzurufen.
Enum-Mitglieder sind Instanzen enum
einer Klasse, auf die statisch zugegriffen werden kann
Elemente enum Season (WINTER, SPRING и т.д.)
sind statisch zugängliche Instanzen enum
der -class Season
. Ihre statische Verfügbarkeit ermöglicht es uns, Vergleiche mit dem Referenzvergleichsoperator durchzuführen ==
. Beispiel:
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
Name und Seriennummer des Enum-Elements
Wie bereits erwähnt,enum
erbt jede Klasse java.lang.Enum
, die eine Reihe von Methoden enthält, die für alle Aufzählungen nützlich sind. Beispiel:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
Die Ausgabe wird sein:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
Die Methoden name()
und toString()
werden hier gezeigt ordinal()
. Die Semantik der Methoden ist offensichtlich. Es ist zu beachten, dass diese Methoden enum
von der Klasse geerbt werden java.lang.Enum
. Abrufen eines Elements enum
anhand der String-Darstellung seines Namens Sehr oft stellt sich die Aufgabe, ein Element anhand seiner String-Darstellung zu ermitteln enum
. Zu diesem Zweck enum
erstellt der Compiler in jeder -Klasse automatisch eine spezielle statische Methode: public static EnumClass valueOf(String name)
, die ein Aufzählungselement EnumClass
mit einem Namen zurückgibt, der gleich ist name
. Anwendungsbeispiel:
String name = "WINTER";
Season season = Season.valueOf(name);
Als Ergebnis der Ausführung des Codes ist die Saisonvariable gleich Season.WINTER
. Bitte beachten Sie, dass eine IllegalArgumentException ausgelöst wird , wenn das Element nicht gefunden wird . Wenn es name
gleich ist null
, wird eine NullPointerException ausgelöst . Das wird übrigens oft vergessen. Aus irgendeinem Grund sind viele fest davon überzeugt, dass, wenn eine Funktion ein Argument akzeptiert und unter bestimmten Bedingungen eine IllegalArgumentException auslöst , bei der Übergabe an diese Funktion null
mit Sicherheit auch eine IllegalArgumentException ausgelöst wird . Aber das ist nebensächlich. Lass uns weitermachen. Alle Elemente einer Aufzählung abrufenenum
Manchmal müssen Sie zur Laufzeit eine Liste aller Elemente einer -Klasse abrufen . Zu diesem Zweck enum
erstellt der Compiler in jeder -class eine Methode public static EnumClass[] values()
. Anwendungsbeispiel:
System.out.println(Arrays.toString(Season.values()));
Wir erhalten die folgende Ausgabe:
[WINTER, SPRING, SUMMER, AUTUMN]
Beachten Sie, dass weder Methode valueOf()
noch Methode values()
in der Klasse definiert sind java.lang.Enum
. Stattdessen werden sie automatisch vom Compiler hinzugefügt, wenn enum
die -Klasse kompiliert wird. Eigene Methoden zur enum
-Klasseenum
hinzufügen Sie haben die Möglichkeit, eigene Methoden sowohl zur -Klasse als auch zu ihren Elementen hinzuzufügen : Das Gleiche, aber mit Polymorphismus: Das letzte Beispiel demonstriert die Verwendung von Vererbung in enum
. Mehr dazu später. Durch Vererbungenum
in Java enum
können Sie eine Klassenhierarchie implementieren, deren Objekte in einer einzigen Instanz erstellt werden und statisch zugänglich sind. In diesem Fall enum
können Elemente ihre eigenen Konstruktoren enthalten. Geben wir ein Beispiel: Hier deklarieren wir eine Aufzählung Type
mit drei Elementen INT
, INTEGER
und STRING
. Der Compiler erstellt die folgenden Klassen und Objekte:
Type
- Klasse abgeleitet vonjava.lang.Enum
INT
— Objekt der 1. Klasse, abgeleitet vonType
INTEGER
— Objekt der 2. Klasse, abgeleitet vonType
STRING
— Objekt der 3. Klasse, abgeleitet vonType
Object parse(String)
und einem polymorphen Konstruktor erstellt Type(..., boolean)
. Gleichzeitig existieren Objekte der Klassen INT
, INTEGER
und STRING
in einer einzigen Kopie und sind statisch zugänglich. Sie können dies überprüfen:
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass() + " " + Type.STRING.getClass().getSuperclass());
Wir erhalten die folgende Ausgabe:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
Es ist ersichtlich, dass der Compiler eine Klasse Type
und drei nested
davon abgeleitete Klassen erstellt hat Type
.
Dekompilierte Enum-Klasse mit Vererbung
Um das oben Gesagte zu bestätigen, präsentieren wir auch das Ergebnis der Dekompilierung der AufzählungType
aus dem obigen Beispiel:
Aufzählungen und parametrischer Polymorphismus
Der Leser fragt sich vielleicht: „ Warum verwendet die obige Typaufzählung keine Generika? “ Tatsache ist, dass in Java die Verwendung von Generikaenum
verboten ist. Daher lässt sich das folgende Beispiel nicht kompilieren:
enum Type<T> {}
Weiteres Studium
Für ein tieferes Verständnis der Funktionsweise von Aufzählungen in Java empfehle ich Ihnen, sich mit dem Quellcode der Klasse vertraut zu machenjava.lang.Enum
und auch den Jad-Decompiler zu verwenden, um den generierten Code zu studieren. Darüber hinaus ist das Studium des Quellcodes der Java-Bibliothek unbedingt erforderlich, um zu verstehen, wie viele Mechanismen in Java funktionieren, und ist als Referenz für objektorientiertes Design nützlich. Link zur Originalquelle: http://alexander.lds.lg.ua/
GO TO FULL VERSION