你好!在本文中,我们将介绍 Java Enums。
想象一下,你分配了以下任务:创建一个实现星期几的类。
乍一看,这似乎相当简单。你的代码如下所示:
注意:我们使用大写字母来指定 Enum 字段。这些是常量,因此它们使用全大写而不是 camelCase。
public class DayOfWeek {
private String title;
public DayOfWeek(String title) {
this.title = title;
}
public static void main(String[] args) {
DayOfWeek dayOfWeek = new DayOfWeek("星期六");
System.out.println(dayOfWeek);
}
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
这些代码看起来很正常,但有这样的问题:你可以将任何文本传递给 DayOfWeek 类的构造方法。这就意味着,有人可以随便创建星期几的名称,比如“青蛙”、“云彩”或“azaza322”。这显然我们不期望出现这种行为,因为一周中只有 7 天,而且每一天都有一个特定的名称。
因此,我们的任务是以某种方式限制 DayOfWeek 类的可能值范围。
在 Java 1.5 面市之前,开发人员必须独立开发自己的解决方案来解决这个问题,因为该语言没有现成的解决方案。
在那些日子里,如果程序员需要限制值的数量,则会这样做:
public class DayOfWeek {
private String title;
private DayOfWeek(String title) {
this.title = title;
}
public static DayOfWeek SUNDAY = new DayOfWeek("星期日");
public static DayOfWeek MONDAY = new DayOfWeek("星期一");
public static DayOfWeek TUESDAY = new DayOfWeek("星期二");
public static DayOfWeek WEDNESDAY = new DayOfWeek("星期三");
public static DayOfWeek THURSDAY = new DayOfWeek("星期四");
public static DayOfWeek FRIDAY = new DayOfWeek("星期五");
public static DayOfWeek SATURDAY = new DayOfWeek("星期六");
@Override
public String toString() {
return "DayOfWeek{" +
"title='" + title + '\'' +
'}';
}
}
你应该注意下面的事项:构造方法为 private。如果构造方法带有 private 修饰符,则不能用于创建对象。而且由于该类只有一个构造方法,因此无法创建任何 DayOfWeek 对象。
public class Main { public static void main(String[] args) { DayOfWeek sunday = new DayOfWeek(); // 错误! } }
当然,该类确实具有所需数量的 public static 对象,这些对象已正确初始化(使用正确的星期几名称)。
这允许这些对象在其他类中使用。
public class Person { 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 个静态常量。我们可以用它们来实现程序。
例如,我们编写一个程序来确定学生今天是否需要上学。学生有一个每日时间表,由 StudentSchedule 类表示:
public class StudentSchedule {
private DayOfWeek dayOfWeek;
// ... 其他字段
public DayOfWeek getDayOfWeek() {
return dayOfWeek;
}
public void setDayOfWeek(DayOfWeek dayOfWeek) {
this.dayOfWeek = dayOfWeek;
}
}
时间表对象的 dayOfWeek 变量确定今天是哪一天。
下面是学生类:
public class Student {
private StudentSchedule schedule;
private boolean goToSchool;
public void wakeUp() {
if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
System.out.println("好哇,可以多睡会了!");
} else {
System.out.println("该死,又要上学了 :(");
}
}
}
在 wakeUp() 方法中,我们使用 Java Enum 来确定学生接下来应该做什么。
我们甚至没有提供有关 DayOfWeek 中每个字段的详细信息,我们也不需要:星期几该干什么那是不言自明。 如果我们就这么使用,任何开发人员都会理解代码中发生了什么。
Enum 方便使用的另一个例子是它的常量可以与 switch 语句一起使用。例如,我们编写一个严格节食的程序,其中的菜肴是按天安排的:
public class VeryStrictDiet {
public void takeLunch(DayOfWeek dayOfWeek) {
switch (dayOfWeek) {
case SUNDAY:
System.out.println("星期日晚餐!你今天甚至可以享受一点甜品。");
break;
case MONDAY:
System.out.println("星期一午餐:鸡汤面!");
break;
case TUESDAY:
System.out.println("星期二,今天是芹菜汤 :(");
break;
//... 诸如此类,直到结束
}
}
}
这是 Enums 与 Java 1.5 之前使用的旧解决方案相比的优势之一 — 旧解决方案不能与 switch 一起使用。你还需要了解什么。
Enum?Enum 是一个真正的类,我们在这方面所做的努力提供了所有可能性。
例如,如果当前星期几的实现不够充分,你可以向 DayOfWeek 添加变量、构造方法和方法:
public enum DayOfWeek {
SUNDAY ("星期日"),
MONDAY ("星期一"),
TUESDAY ("星期二"),
WEDNESDAY ("星期三"),
THURSDAY ("星期四"),
FRIDAY ("星期五"),
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 有一个严重缺陷,即不能被继承。
此外,枚举包含特征方法:values():返回 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); }
输出:
0valueOf():返回与传递的名称对应的 Enum 对象:
public static void main(String[] args) { DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY"); System.out.println(sunday); }
输出:
DayOfWeek{title = '星期日'}

GO TO FULL VERSION