77. Java 枚举类 - 什么时候使用枚举?

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() 返回 0TUESDAY.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) 返回负值,表示 MONDAYFRIDAY 之前。

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() 可以重写,提供更友好的描述

希望这个讲解能帮你更清楚地理解 枚举的访问、计算和比较!🚀 🎯

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容