你好!在这篇文章中,我将向您介绍 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