77. Java 枚举类 - 什么时候使用枚举?
✅ 适合使用枚举的情况
- 变量只能有固定的几个值(比如:星期、月份、交通灯颜色)。
- 需要更安全、更直观的代码(避免拼写错误,防止非法值)。
-
枚举值需要有额外信息或行为(比如
isWeekday()
、display()
)。
❌ 不适合使用枚举的情况
- 值的范围是动态的(比如:数据库查询的用户角色)。
- 值的范围特别大(比如:用户 ID、订单编号)。
如何访问、计算和比较枚举?
在 Java 中,枚举是一种特殊的类,它的所有实例都是编译时确定的常量。我们可以用 ==
来比较枚举值,也可以在 switch
语句或表达式中使用它们,从而写出更可读、安全**的代码。
1️⃣ 枚举值可以当作常量
DayOfWeek weekStart = DayOfWeek.MONDAY;
📌 解析
-
weekStart
是一个DayOfWeek
类型的变量,它的值是MONDAY
。 - 枚举值本质上是常量,所以可以直接赋值给枚举变量。
2️⃣ 用 ==
比较枚举
在 Java 中,枚举值是单例的(JVM
只会创建一个实例),所以可以用 ==
直接比较,而不需要 equals()
方法。
if (weekStart == DayOfWeek.MONDAY) {
System.out.println("The week starts on Monday.");
}
✅ 为什么用 ==
比 equals()
更好?
- 性能更高(不涉及对象比较,直接比较引用)。
-
更安全(不会出现
NullPointerException
)。 -
更直观(
weekStart == DayOfWeek.MONDAY
可读性比weekStart.equals(DayOfWeek.MONDAY)
高)。
3️⃣ 用 switch
处理枚举
传统 switch
语法
DayOfWeek someDay = DayOfWeek.FRIDAY;
switch (someDay) {
case MONDAY:
System.out.println("The week just started.");
break;
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
System.out.println("We are somewhere in the middle of the week.");
break;
case FRIDAY:
System.out.println("The weekend is near.");
break;
case SATURDAY:
case SUNDAY:
System.out.println("Weekend");
break;
default:
throw new AssertionError("Should not happen");
}
📌 解析
-
switch
语句让代码更清晰,不需要写多个if-else
。 -
多个
case
可以合并(比如TUESDAY, WEDNESDAY, THURSDAY
共享同一个case
)。 -
必须加
break
,否则会继续执行下一个case
(除非使用->
语法)。
4️⃣ 用 switch
表达式(Java 12+)
Java 12
引入了 switch
表达式,让代码更简洁。
DayOfWeek someDay = DayOfWeek.FRIDAY;
switch (someDay) {
case MONDAY -> System.out.println("The week just started.");
case TUESDAY, WEDNESDAY, THURSDAY -> System.out.println("We are somewhere in the middle of the week.");
case FRIDAY -> System.out.println("The weekend is near.");
case SATURDAY, SUNDAY -> System.out.println("Weekend");
default -> throw new AssertionError("Should not happen");
}
✅ switch
表达式的优势
-
不需要
break
,每个case
只会执行对应的代码。 -
语法更简洁,
->
让代码更直观。 -
编译器检查完备性,如果
switch
里没有处理所有可能的enum
值,会报错。
5️⃣ switch
表达式返回值
switch
也可以返回值,让代码更简洁:
DayOfWeek someDay = DayOfWeek.FRIDAY;
String text = switch (someDay) {
case MONDAY -> "The week just started.";
case TUESDAY, WEDNESDAY, THURSDAY -> "We are somewhere in the middle of the week.";
case FRIDAY -> "The weekend is near.";
case SATURDAY, SUNDAY -> "Weekend";
};
System.out.println(text);
📌 解析
-
switch
语句可以直接作为表达式赋值。 -
不用
break
,代码更清晰。 -
如果漏掉某个
case
,编译器会报错,保证逻辑完备。
6️⃣ 遍历所有枚举值
Java
提供了 values()
方法,可以获取所有的枚举值:
for (DayOfWeek day : DayOfWeek.values()) {
System.out.println(day);
}
📌 解析
-
DayOfWeek.values()
返回DayOfWeek
枚举的所有值。 -
可以用
for
循环遍历所有枚举常量。
💡 输出
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
7️⃣ 枚举的 ordinal()
方法
Java 枚举默认有一个 ordinal()
方法,返回枚举的索引(从 0
开始)。
DayOfWeek day = DayOfWeek.WEDNESDAY;
System.out.println(day + " is at position: " + day.ordinal());
💡 输出
WEDNESDAY is at position: 2
📌 解析
-
MONDAY.ordinal()
返回0
,TUESDAY.ordinal()
返回1
,以此类推。 -
不推荐用
ordinal()
来代替数值,因为如果修改了枚举的顺序,ordinal()
值会改变,容易引发 Bug。
8️⃣ 枚举的 compareTo()
方法
枚举默认实现了 compareTo()
方法,可以用 compareTo()
进行顺序比较:
DayOfWeek d1 = DayOfWeek.MONDAY;
DayOfWeek d2 = DayOfWeek.FRIDAY;
if (d1.compareTo(d2) < 0) {
System.out.println(d1 + " comes before " + d2);
} else {
System.out.println(d1 + " comes after " + d2);
}
💡 输出
MONDAY comes before FRIDAY
📌 解析
-
compareTo()
按ordinal()
值比较顺序。 -
MONDAY.compareTo(FRIDAY)
返回负值,表示MONDAY
在FRIDAY
之前。
9️⃣ 枚举的 name()
和 toString()
方法
-
name()
方法返回 枚举常量的名字(字符串)。 -
toString()
方法默认和name()
一样,但可以被重写。
DayOfWeek day = DayOfWeek.MONDAY;
System.out.println(day.name()); // 输出: MONDAY
System.out.println(day.toString()); // 输出: MONDAY
如果我们重写 toString()
:
public enum DayOfWeek {
MONDAY {
public String toString() {
return "Start of the week";
}
},
FRIDAY {
public String toString() {
return "Almost weekend";
}
},
SUNDAY {
public String toString() {
return "Relaxing day";
}
};
}
💡 输出
Start of the week
🔹 总结
方法 | 作用 |
---|---|
== |
比较两个枚举是否相等(推荐使用) |
switch |
在 switch 语句中使用枚举,提高可读性 |
values() |
获取所有枚举值(for 循环遍历) |
ordinal() |
返回枚举的索引(从 0 开始) |
compareTo() |
按枚举顺序比较大小 |
name() |
获取枚举的名称(字符串) |
toString() |
可以重写,提供更友好的描述 |
希望这个讲解能帮你更清楚地理解 枚举的访问、计算和比较!🚀 🎯