枚举
在 java 中,我们可以通过 static final
来定义常量。例如,定义一周的七天:
java
class Weekday {
public static final int SUN = 0;
public static final int MON = 1;
public static final int TUE = 2;
public static final int WED = 3;
public static final int THU = 4;
public static final int FRI = 5;
public static final int SAT = 6;
}
之后可以这样使用常量:
java
int day = 1;
if (day == Weekday.MON || day == Weekday.FRI) {
System.out.println("working...");
}
但是,这样定义了之后,有一个严重的问题就是编译阶段无法检查每个值的合理性,例如:
java
//可以正常编译,但我们想要 today 只能是 0 - 6
int today = 9999;
if (today == Weekday.MON || today == Weekday.FRI) {
System.out.println("working...");
}
enum
为了能让编译器自动检查某个值是否在枚举定义范围内,这时就可以使用 enum
来定义枚举类。
java
enum Weekday {
SUN, MON, TUE, WED, THU, FRI, SAT;
}
public static void main(String[] args) {
Weekday day = Weekday.MON;
if (day == Weekday.MON || day == Weekday.FRI) {
System.out.println("working...");
}
}
与 int
定义的常量相比,使用 enum
定义枚举有以下好处:
enum
枚举本身带有类型信息,即Weekday.MON
的类型是Weekday
,编译器会自动检查类型错误;- 不可能引用到枚举中未定义的值,因为编译无法通过;
枚举比较
使用 enum
定义的枚举类是一种引用类型。
正常情况下,引用类型比较,需要使用 equals()
方法,因为使用 ==
比较,他比较的是两个引用类型的地址值是否相同。
但是,enum 定义的枚举类型例外。
因为 enum
定义的枚举类型,每个常量在 JVM 中只有一个唯一实例,所以可以直接使用 ==
比较:
java
Weekday day = Weekday.MON;
if (day == Weekday.MON || day == Weekday.FRI) {
System.out.println("working...");
}
if (day.equals(Weekday.MON)) {
System.out.println("working...");
}
常用方法
方法 | 描述 |
---|---|
name() | 返回常量名称(方法不可被重写) |
toString() | 返回常量名称(方法可被重写) |
ordinal() | 返回枚举常量的顺序,从 0 开始计数 |
java
String s = Weekday.MON.name();
System.out.println(s); // "MON"
String s1 = Weekday.MON.toString();
System.out.println(s1); // "MON"
int n = Weekday.MON.ordinal();
System.out.println(n); // 1
高级用法
enum
定义的枚举,其内部默认使用一个构造器的,我们也可以手动添加构造器,实现为枚举值添加顺序值和中文名称的效果。
java
enum Weekday {
SUN(0, "星期天"),
MON(1, "星期一"),
TUE(2, "星期二"),
WED(3, "星期三"),
THU(4, "星期四"),
FRI(5, "星期五"),
SAT(6, "星期六");
public final int dayValue;
private final String name;
Weekday(int dayValue, String name) {
this.dayValue = dayValue;
this.name = name;
}
@Override
public String toString() {
return this.name;
}
}
java
public static void main(String[] args) {
Weekday day = Weekday.MON;
System.out.println(day.dayValue); // 1
System.out.println(day.toString()); // "星期一"
System.out.println(day.name()); // "MON"
}
注意
如果想获取枚举常量的名字,首选 name()
方法,而不是 toString()
。