76. Java 枚举类 - 什么是枚举?

164 阅读3分钟

76. Java 枚举类 - 什么是枚举?

Java 中,我们有时候会遇到 某个变量只能有固定几个值 的情况,比如:

  • 星期(只能是周一到周日)
  • 性别(只能是男性、女性)
  • 方向(只能是东、南、西、北)

如果用普通的 intString 来表示,可能会遇到 非法值(比如 "hello" 作为星期,999 作为方向),这时候 Java 枚举(Enum 就能帮我们解决问题!


枚举的特点

是一种特殊的类,但只能有 有限个实例(不能动态创建新实例)。 ✅ 所有实例在编译时已知,可以避免非法值。 ✅ 更加可读、可维护,比 intString 更安全。 ✅ 默认继承 java.lang.Enum,不能再继承其他类(但可以实现接口)。


如何定义枚举?

Java 中,定义枚举和定义类很像,但用 enum 关键字,而不是 class

示例:定义一周的七天

public enum DayOfWeek {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

📌 代码解析

  • 这里DayOfWeek是一个 枚举类型,它的 7 个值(枚举常量)是:

    • MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
  • 不能创建新的 DayOfWeek 实例,枚举实例 只能是定义的这 7 个


使用枚举

枚举的使用方式和普通类的静态变量很像,我们可以:

  1. 定义枚举变量
  2. 给枚举变量赋值
  3. switch 语句中使用

示例 1:声明枚举变量

public class EnumExample {
    public static void main(String[] args) {
        DayOfWeek today = DayOfWeek.FRIDAY;
        System.out.println("Today is: " + today);
    }
}

💡 输出

Today is: FRIDAY

📌 DayOfWeek today = DayOfWeek.FRIDAY;

  • 这里 定义了一个 DayOfWeek 类型的变量 today,并赋值 FRIDAY

枚举在 switch 语句中的使用

枚举可以用在 switch 语句中,使代码更清晰:

示例 2:用枚举实现 switch 语句

public class EnumSwitchExample {
    public static void main(String[] args) {
        DayOfWeek today = DayOfWeek.FRIDAY;

        switch (today) {
            case MONDAY:
                System.out.println("It's Monday. Back to work!");
                break;
            case FRIDAY:
                System.out.println("It's Friday! Weekend is coming!");
                break;
            case SUNDAY:
                System.out.println("It's Sunday. Time to relax!");
                break;
            default:
                System.out.println("Just another regular day.");
        }
    }
}

💡 输出

It's Friday! Weekend is coming!

📌 为什么用枚举更好?

  • 可读性更高FRIDAY"Friday" 更直观)。
  • 编译器会检查错误(不能拼写错,比如 "Fridy" 会直接报错)。
  • 避免非法值(比如 999 作为星期)。

枚举的高级用法

枚举不仅仅是 MONDAY, TUESDAY... 这些简单的值,它其实是一个 完整的类,可以: ✅ 添加字段(变量)添加构造方法添加方法


示例 3:枚举可以有字段和方法

假设我们想给 DayOfWeek 加上“是否是工作日” 的信息:

public enum DayOfWeek {
    MONDAY(true), TUESDAY(true), WEDNESDAY(true), 
    THURSDAY(true), FRIDAY(true), 
    SATURDAY(false), SUNDAY(false);

    private final boolean isWeekday;

    // 构造方法(private,自动调用)
    DayOfWeek(boolean isWeekday) {
        this.isWeekday = isWeekday;
    }

    // 获取是否是工作日
    public boolean isWeekday() {
        return isWeekday;
    }
}

public class EnumExample {
    public static void main(String[] args) {
        DayOfWeek today = DayOfWeek.FRIDAY;
        System.out.println("Today is " + today + ", is it a weekday? " + today.isWeekday());
    }
}

💡 输出

Today is FRIDAY, is it a weekday? true

📌 代码解析

  • 枚举常量变成了 MONDAY(true) 这种形式,每个枚举都存了一个 isWeekday 的值。
  • DayOfWeek(boolean isWeekday) 是构造方法,每个枚举常量都会调用它。
  • isWeekday() 方法 可以获取 true/false,判断这一天是不是工作日。

枚举可以实现接口

虽然 枚举不能继承类,但可以实现接口

示例 4:枚举实现接口

interface Displayable {
    void display();
}

public enum TrafficLight implements Displayable {
    RED("Stop"), GREEN("Go"), YELLOW("Caution");

    private final String message;

    TrafficLight(String message) {
        this.message = message;
    }

    @Override
    public void display() {
        System.out.println("Traffic light: " + this + " - " + message);
    }
}

public class EnumInterfaceExample {
    public static void main(String[] args) {
        for (TrafficLight light : TrafficLight.values()) {
            light.display();
        }
    }
}

💡 输出

Traffic light: RED - Stop
Traffic light: GREEN - Go
Traffic light: YELLOW - Caution

📌 代码解析

  • TrafficLight 实现了 Displayable 接口,并定义了 display() 方法。
  • 枚举可以用 for 循环遍历TrafficLight.values() 返回所有的枚举常量。

总结

特性枚举
定义方式enum 关键字
实例个数固定,不能动态创建
默认继承java.lang.Enum
是否能有字段/方法✅ 可以
是否能实现接口✅ 可以
是否能继承类❌ 不能
使用场景只有有限个可能值的类型,比如 星期、颜色、性别、方向