Skip to content

枚举类

枚举类型本质上也是一种类,只不过是这个类的对象是有限个,不能让用户随意创建。

经典声明

在JDK5声明一个枚举类:

java
public class Color {

    // 1. 定义常量对象
    public static final Color RED = new Color("RED");
    public static final Color GREEN = new Color("GREEN");
    public static final Color BLUE = new Color("BLUE");

    // 2. 属性
    private String name;

    // 3. 构造方法私有化(防止外部 new)
    private Color(String name) {
        this.name = name;
    }

    // 4. 提供 getter
    public String getName() {
        return name;
    }

    // 5. toString(可选)
    @Override
    public String toString() {
        return name;
    }
}

构造方法必须是 private

java
private Color(String name)
  • 防止外部创建新对象,保证枚举值是固定的

所有实例都是 public static final

java
public static final Color RED = new Color("RED");
  • public:外部可访问
  • static:类级别,全局唯一
  • final:不能被修改引用

控制实例数量

整个类中只有这几个对象:

java
RED / GREEN / BLUE

enum声明枚举类

  • 枚举类的常量对象列表必须在枚举类的首行,因为是常量,所以建议大写。

  • 枚举类默认继承的是 java.lang.Enum 类,因此不能再继承其他的类型。

  • 枚举对象使用,分隔,如果常量对象列表后面没有其他代码,那么可以省略,否则不可以省略

java
public enum Status {
    ACTIVE, INACTIVE, PENDING, REJECTED
}
java
package org.example;

public enum Season {
    SPRING("春天", "温暖"),
    SUMMER("夏天", "炎热"),
    AUTUMN("秋天", "凉爽"),
    WINTER("冬天", "寒冷");

    private final String name;
    private final String desc;

    Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }
}

使用枚举类

java
public class EnumIfExample {
    public static void main(String[] args) {
        Season season = Season.SPRING;

        if (season == Season.SPRING) {
            System.out.println("春天来了,万物复苏!");
        } else if (season == Season.SUMMER) {
            System.out.println("夏天炎热,适合游泳。");
        } else if (season == Season.AUTUMN) {
            System.out.println("秋天收获的季节。");
        } else if (season == Season.WINTER) {
            System.out.println("冬天寒冷,要注意保暖。");
        }

        // 遍历所有枚举值
        System.out.println("所有季节:");
        for (Season s : Season.values()) {
            System.out.println(s);
        }

        // 根据字符串获取枚举值
        String seasonName = "WINTER";
        Season s2 = Season.valueOf(seasonName);
        System.out.println("从字符串获取的季节: " + s2);
    }
}

Enum类

toString

java
public String toString()

Enum重写了toString方法:默认返回的是常量名(对象名,value),可以继续手动重写该方法

java
System.out.println(Season.SPRING);//SPRING

static values

java
static 枚举类型[] values()

被子类重写:返回所有枚举成员组成的数组。

java
for (Season s : Season.values()) {
    System.out.println(s);
}
//SPRING
//SUMMER
//AUTUMN
//WINTER

static valueOf

java
static 枚举类型 valueOf(String name)

被子类重写:可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常IllegalArgumentException

java
Season spring = Season.valueOf("SPRING");
System.out.println(spring);

name

得到当前枚举常量的名称

java
public final String name()
java
System.out.println(Season.SPRING.name());//SPRING

ordinal

返回枚举变量的定义顺序,顺序从0开始

java
public final int ordinal()
java
System.out.println(Season.valueOf("SUMMER").ordinal());//1

枚举类编译

枚举常量初始化

  • 枚举类的常量对象列表系统会自动添加 public static final 修饰。

  • 编译器会自动向构造函数传入nameordinal

java
enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}
java
public static final Season SPRING = new Season("SPRING", 0);
public static final Season SUMMER = new Season("SUMMER", 1);
public static final Season AUTUMN = new Season("AUTUMN", 2);
public static final Season WINTER = new Season("WINTER", 3);

构造方法

默认生成构造方法:

java
private Season(String name, int ordinal) {
    super(name, ordinal);
}

我们也可以自己添加构造方法,构造方法的 private 可以省略

java
public enum Season {
    SPRING("春天", "温暖"),
    SUMMER("夏天", "炎热"),
    AUTUMN("秋天", "凉爽"),
    WINTER("冬天", "寒冷");

    private final String name;
    private final String desc;

    Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }
}
java
public final class Season extends Enum<Season> {

    public static final Season SPRING = new Season("SPRING", 0, "春天", "温暖");
    public static final Season SUMMER = new Season("SUMMER", 1, "夏天", "炎热");
    public static final Season AUTUMN = new Season("AUTUMN", 2, "秋天", "凉爽");
    public static final Season WINTER = new Season("WINTER", 3, "冬天", "寒冷");

    private final String name;
    private final String desc;

    private Season(String enumName, int ordinal, String name, String desc) {
        super(enumName, ordinal); // 👈 关键:传给 Enum
        this.name = name;
        this.desc = desc;
    }
}

重写方法

编译器自动为我们重写了父类Enum的valuesvalueOf方法

  • values
java
public static Season[] values() {
    return new Season[]{SPRING, SUMMER, AUTUMN, WINTER};
}
  • valueOf
java
public static Season valueOf(String name) {
    return Enum.valueOf(Season.class, name);
}

switch与枚举

switch 的表达式是一个枚举类型时,case 标签中不需要写枚举类名,直接写枚举常量即可。

java
Season season = Season.SPRING;

switch (season) {
    case SPRING:
        System.out.println("春天");
        break;
    case SUMMER:
        System.out.println("夏天");
        break;
    case AUTUMN:
        System.out.println("秋天");
        break;
    case WINTER:
        System.out.println("冬天");
        break;
}

枚举实现接口

  • 所有枚举值共享同一个实现
java
public enum Season implements SeasonBehavior {
    SPRING, SUMMER, AUTUMN, WINTER;

    @Override
    public String getDesc() {
        return "默认描述";
    }
}
  • 每个枚举不同实现
java
public enum Season implements SeasonBehavior {

    SPRING("春天", "温暖") {
        @Override
        public String getDesc() {
            return name + ",万物复苏";
        }
    },
    SUMMER("夏天", "炎热") {
        @Override
        public String getDesc() {
            return name + ",很热";
        }
    },
    AUTUMN("秋天", "凉爽") {
        @Override
        public String getDesc() {
            return name + ",适合出游";
        }
    },
    WINTER("冬天", "寒冷") {
        @Override
        public String getDesc() {
            return name + ",要穿羽绒服";
        }
    };

    protected final String name;
    protected final String climate;

    Season(String name, String climate) {
        this.name = name;
        this.climate = climate;
    }
}

比 switch更加优雅:

java
String desc = switch (season) {
    case SPRING -> "春天";
    case SUMMER -> "夏天";
    case AUTUMN -> "秋天";
    case WINTER -> "冬天";
};

HowToUse

选择 常量还是枚举,取决于你业务的复杂度和可维护性:

  • 简单值判断 → 常量够用。
  • 逻辑复杂、有扩展性 → 枚举更好。