Aufzählungstyp. Aufzählungsklasse. Intern eine Klasse, die von der Klasse java.lang.Enum erbt. [^ 1]
[^ 1]: Die Vererbung von java.lang.Enum erfolgt durch den Compiler. Der Programmierer kann die Klasse nicht explizit erben.
Weitere Informationen zu enum finden Sie in Kapitel 6 des Buches "Effective Java". Der Autor, Joshua Bloch, ist der Spezifikationsleiter für JSR 201.
Konstante Deklarationen, die nur zur Unterscheidung bestimmt waren, wurden zunächst im int enum pattern [^ 2] beschrieben.
CalendarConst.java
public final static int JANUARY = 0;
public final static int FEBRUARY = 1;
public final static int MARCH = 2;
public final static int APRIL = 3;
public final static int MAY = 4;
public final static int JUNE = 5;
public final static int JULY = 6;
public final static int AUGUST = 7;
public final static int SEPTEMBER = 8;
public final static int OCTOBER = 9;
public final static int NOVEMBER = 10;
public final static int DECEMBER = 11;
public final static int UNDECIMBER = 12;
Das Int-enum-Muster verhinderte wirksam das Auftreten magischer Zahlen, hatte jedoch die folgenden Probleme.
Keine Typgarantie Da es sich um ein int handelt, ist es möglich, bedeutungslose Beschreibungen vorzunehmen, z. B. einen irrelevanten int-Wert zu übergeben oder zwei Konstanten hinzuzufügen.
Es gibt keinen Namespace Sie müssen der Konstante eine Zeichenfolge voranstellen, um Konflikte mit anderen Aufzählungstypen zu vermeiden.
Sicherheitslücke Die int-Aufzählung ist eine Konstante zur Kompilierungszeit. Wenn eine neue Konstante zwischen zwei vorhandenen Konstanten hinzugefügt wird oder die Reihenfolge geändert wird, muss der Client neu kompiliert werden. Wenn Sie es nicht kompilieren, können Sie es ausführen, aber das Verhalten ist unvorhersehbar.
Der Ausgabewert hat keinen Informationswert Alle Ausgänge sind numerisch. Ich weiß nicht, was es bedeutet, und ich weiß nicht einmal, was es ist.
[^ 2]: Derzeit ist es ein Anti-Muster.
Das typsichere Enum-Muster löst das Problem des Int-Enum-Musters. Aufzählungskonstanten werden in einer Singleton-Klasse bereitgestellt.
MonthEnum.java
public class MonthEnum {
private final String name;
private final int ordinal;
private Month(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
public String name() {
return name;
}
public int getValue()
{
return ordinal() + 1;
}
public String toString() {
return name;
}
public static final Month JANUARY = new Month("JANUARY", 0);
public static final Month FEBRUARY = new Month("FEBRUARY", 1);
public static final Month MARCH = new Month("MARCH", 2);
public static final Month APRIL = new Month("APRIL", 3);
public static final Month MAY = new Month("MAY", 4);
public static final Month JUNE = new Month("JUNE", 5);
public static final Month JULY = new Month("JULY", 6);
public static final Month AUGUST = new Month("AUGUST", 7);
public static final Month SEPTEMBER = new Month("SEPTEMBER", 8);
public static final Month OCTOBER = new Month("OCTOBER", 9);
public static final Month NOVEMBER = new Month("NOVEMBER", 10);
public static final Month DECEMBER = new Month("DECEMBER", 11);
}
Dies ist die Standardbeschreibungsmethode vor dem Aufkommen von enum (vor Java 5).
enum In Java5 oder höher kann die Aufzählungsklasse (Aufzählungstyp) verwendet werden.
Month.java
public enum Month {
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER;
public int getValue() {
return ordinal() + 1;
}
}
Obwohl es sich um eine kurze Beschreibung handelt, handelt es sich im Prinzip um eine Erweiterung des typsicheren Aufzählungsmusters. Sie können bestätigen, dass das typsichere Aufzählungsmuster angewendet wird, indem Sie die Klassendatei dekompilieren, die die Aufzählungsklasse kompiliert. Das Ergebnis der umgekehrten Kompilierung ist unten dargestellt.
Month.jad
public final class Month extends Enum
{
private Month(String s, int i)
{
super(s, i);
}
public int getValue()
{
return ordinal() + 1;
}
public static Month[] values()
{
Month amonth[];
int i;
Month amonth1[];
System.arraycopy(amonth = ENUM$VALUES, 0, amonth1 = new Month[i = amonth.length], 0, i);
return amonth1;
}
public static Month valueOf(String s)
{
return (Month)Enum.valueOf(g06_enum/Month, s);
}
public static final Month JANUARY;
public static final Month FEBRUARY;
public static final Month MARCH;
public static final Month APRIL;
public static final Month MAY;
public static final Month JUNE;
public static final Month JULY;
public static final Month AUGUST;
public static final Month SEPTEMBER;
public static final Month OCTOBER;
public static final Month NOVEMBER;
public static final Month DECEMBER;
private static final Month ENUM$VALUES[];
static
{
JANUARY = new Month("JANUARY", 0);
FEBRUARY = new Month("FEBRUARY", 1);
MARCH = new Month("MARCH", 2);
APRIL = new Month("APRIL", 3);
MAY = new Month("MAY", 4);
JUNE = new Month("JUNE", 5);
JULY = new Month("JULY", 6);
AUGUST = new Month("AUGUST", 7);
SEPTEMBER = new Month("SEPTEMBER", 8);
OCTOBER = new Month("OCTOBER", 9);
NOVEMBER = new Month("NOVEMBER", 10);
DECEMBER = new Month("DECEMBER", 11);
ENUM$VALUES = (new Month[] {
JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER,
NOVEMBER, DECEMBER
});
}
}
Es ist eine Singleton-Klasse, die die Enum-Klasse durch Anwenden des typsicheren Aufzählungsmusters erbt. Die Werte und valueOf-Methoden, ENUM $ VALUES usw. werden vom Compiler automatisch generiert. [^ 3]
[^ 3]: Der zuvor erstellte getValue ist eine Instanzmethode, aber values und valueOf sind Klassenmethoden der Month-Klasse.
Month.java
public enum Month {
JANUARY(1),
FEBRUARY(2),
MARCH(3),
private int monthNumber;
private Month(int param) {
monthNumber = param;
}
}
Es ist wie folgt zusammengestellt.
Month.jad
public final class Month extends Enum
{
private Month(String s, int i, int param)
{
super(s, i);
monthNumber = param;
}
public static Month[] values(){/*Kürzung*/}
public static Month valueOf(String s){/*Kürzung*/}
public static final Month JANUARY;
public static final Month FEBRUARY;
public static final Month MARCH;
private int monthNumber;
private static final Month ENUM$VALUES[];
static
{
JANUARY = new Month("JANUARY", 0, 1);
FEBRUARY = new Month("FEBRUARY", 1, 2);
MARCH = new Month("MARCH", 2, 3);
ENUM$VALUES = (new Month[] {
JANUARY, FEBRUARY, MARCH
});
}
}
Da es eine Vererbungsbeziehung mit der Klasse java.lang.Enum hat, können Sie Enum API verwenden. ..
Recommended Posts