你好!在這篇文章中,我將向您介紹 Java 枚舉。想像一下,您被賦予了一項任務:創建一個實現星期幾的類別。乍一看,這並不複雜,您的程式碼將如下所示:
隨著 Java 1.5 的發布,該語言為此類情況引入了現成的解決方案 - Enum枚舉。 枚舉也是一個類別。但它是專門為解決與我們類似的問題而「量身定制」的:創造一定範圍內的有限價值。由於 Java 的創建者已經有了現成的範例(例如 C 語言,其中已經存在Enum),因此他們能夠創建最佳選項。
public class DayOfWeek {
private String title;
public DayOfWeek(String title) {
this.title = title;
}
public static void main(String[] args) {
DayOfWeek dayOfWeek = new DayOfWeek("Saturday");
System.out.println(dayOfWeek);
}
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
一切似乎都很好,但有一個問題:您可以將任何文字傳遞給DayOfWeek類別的建構子。這樣,某人就可以創建星期幾「Frog」、「Cloud」或「azaza322」。這顯然不是我們期望的行為,因為一周中只有 7 天,而且每一天都有一個名字。因此,我們的任務是以某種方式限制「星期幾」類別的可能值的範圍。在 Java 1.5 之前,由於語言本身沒有現成的解決方案,開發人員被迫自己想出一個解決方案來解決這個問題。在那些日子裡,如果情況需要有限數量的值,他們會這樣做:
public class DayOfWeek {
private String title;
private DayOfWeek(String title) {
this.title = title;
}
public static DayOfWeek SUNDAY = new DayOfWeek("Sunday");
public static DayOfWeek MONDAY = new DayOfWeek("Monday");
public static DayOfWeek TUESDAY = new DayOfWeek("Tuesday");
public static DayOfWeek WEDNESDAY = new DayOfWeek("Wednesday");
public static DayOfWeek THURSDAY = new DayOfWeek("Thursday");
public static DayOfWeek FRIDAY = new DayOfWeek("Friday");
public static DayOfWeek SATURDAY = new DayOfWeek("Saturday");
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
這裡要注意的是:
-
私有構造函數。如果建構函式被標記為private修飾符,則不能使用該建構函式建立該類別的物件。而且由於類別中只有一個建構函數,因此根本無法建立DayOfWeek物件。
public class Main { public static void main(String[] args) { DayOfWeek sunday = new DayOfWeek();//error! } }
-
同時,該類別包含所需數量的公共靜態對象,這些對像以我們需要的方式初始化(日期的名稱是正確的)。
這使得在其他類別中使用物件成為可能。
public class Man { public static void main(String[] args) { DayOfWeek sunday = DayOfWeek.SUNDAY; System.out.println(sunday); } }
結論:
DayOfWeek{title='星期日'}
什麼是枚舉?
那麼,Java 中的 Enum是什麼呢?讓我們來看看同一個DayOfWeek的範例:public enum DayOfWeek {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
它看起來已經簡單多了:) 在我們的Enum內部有 7 個具有靜態存取的常數。我們已經可以使用它來實現程式中的邏輯了。例如,讓我們寫一個程式來確定學生今天是否需要去學校。我們的學生將有自己的日常生活,由ScholarSchedule類別指定:
public class ScholarSchedule {
private DayOfWeek dayOfWeek;
//...other fields
public DayOfWeek getDayOfWeek() {
return dayOfWeek;
}
public void setDayOfWeek(DayOfWeek dayOfWeek) {
this.dayOfWeek = dayOfWeek;
}
}
日模式的dayOfWeek 變數決定今天是哪一天。這是我們學生的班級:
public class Scholar {
private ScholarSchedule schedule;
private boolean goToSchool;
public void wakeUp() {
if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
System.out.println("Hooray, you can sleep some more!");
} else {
System.out.println("Damn, back to school :(");
}
}
}
在wakeUp()方法中,我們使用枚舉來確定學生的進一步操作。我們甚至沒有詳細描述DayOfWeek中每個變數的含義,而且這是沒有必要的:星期幾的機制已經很明顯了,如果我們以當前的形式使用它,任何開發人員都會明白什麼正在您的程式碼中發生。Enum便利性的另一個例子是它的常數可以與switch 語句一起使用。例如,我們正在編寫一個嚴格飲食的程序,其中按天安排膳食:
public class VeryStrictDiet {
public void takeLunch(DayOfWeek dayOfWeek) {
switch (dayOfWeek) {
case SUNDAY:
System.out.println("Sunday lunch! Today you can even have a little sweet");
break;
case MONDAY:
System.out.println("Monday Lunch: Chicken Noodles!");
break;
case TUESDAY:
System.out.println("Tuesday, today is celery soup :(");
break;
//...and so on until the end
}
}
}
這是Enum 相對於 Java 1.5 之前使用的舊解決方案的 優勢之一:舊解決方案無法與switch一起使用。
關於 Enum 類,您還需要了解什麼?
枚舉類別是一個真正的類,具有它附帶的所有功能。例如,如果目前的星期幾的實作對您來說還不夠,您可以為DayOfWeek添加變數、建構子和方法 :public enum DayOfWeek {
SUNDAY ("Sunday"),
MONDAY ("Monday"),
TUESDAY ("Tuesday"),
WEDNESDAY ("Wednesday"),
THURSDAY ("Thursday"),
FRIDAY ("Friday"),
SATURDAY ("Saturday");
private String title;
DayOfWeek(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
我們的Enum 常數現在有一個title字段、一個 getter 和一個重寫的toString方法。與常規類別相比,Enum有一個嚴重的限制——它不能被繼承。此外,枚舉還有其獨特的方法:
-
value() :傳回Enum中儲存的所有值的陣列:
public static void main(String[] args) { System.out.println(Arrays.toString(DayOfWeek.values())); }
結論:
[DayOfWeek{title='星期日'}、DayOfWeek{title='星期一'}、DayOfWeek{title='星期二'}、DayOfWeek{title='星期三'}、DayOfWeek{title='星期四'}、DayOfWeek{title = '星期五'},DayOfWeek{title='星期六'}]
-
ordinal():傳回常數的序數。倒數計時從零開始:
public static void main(String[] args) { int sundayIndex = DayOfWeek.SUNDAY.ordinal(); System.out.println(sundayIndex); }
結論:
0
- valueOf():傳回與給定名稱對應的Enum物件:
public static void main(String[] args) { DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY"); System.out.println(sunday); }
結論:
DayOfWeek{title='星期日'}
GO TO FULL VERSION