Java 枚举类

背景与动机#

有些数据的取值范围是固定的,比如星期、订单状态、季节、支付方式。这类场景如果只用字符串或整数常量,代码容易写错,也不够直观。

枚举类就是为这类“取值有限、语义明确”的场景准备的。

核心原理拆解#

1. enum 用来定义固定常量集合#

enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}

这里的四个枚举常量不是普通字符串,而是 Season 类型的四个固定对象。

2. 枚举比字符串常量更安全#

Season season = Season.SPRING;

如果用字符串,很容易写成 "sprng" 这种拼写错误;用枚举时,编译器就能帮你发现问题。

3. 枚举可以有字段、方法、构造方法#

枚举本质上也是一种特殊类,所以不只是“列几个常量”:

enum Status {
CREATED("已创建"),
PAID("已支付"),
FINISHED("已完成");
private final String text;
Status(String text) {
this.text = text;
}
public String getText() {
return text;
}
}

枚举构造方法默认是私有的,不能手动 new

4. 枚举常和 switch 一起使用#

switch (status) {
case CREATED:
System.out.println("待付款");
break;
case PAID:
System.out.println("待发货");
break;
case FINISHED:
System.out.println("已完成");
break;
}

这让状态分支比字符串判断更清晰、更安全。

5. 枚举自带一些常用方法#

Status s = Status.valueOf("PAID");
Status[] values = Status.values();
System.out.println(s.name());
System.out.println(s.ordinal());

常见方法含义:

  • values():返回全部枚举常量
  • valueOf(String):按名字取枚举常量
  • name():返回常量名
  • ordinal():返回声明顺序下标

实际业务里可以了解 ordinal(),但不建议把它当稳定业务值长期依赖。

最小可运行代码示例#

public class EnumDemo {
public static void main(String[] args) {
Status status = Status.PAID;
System.out.println(status.getText());
for (Status item : Status.values()) {
System.out.println(item.name());
}
}
}
enum Status {
CREATED("已创建"),
PAID("已支付"),
FINISHED("已完成");
private final String text;
Status(String text) {
this.text = text;
}
public String getText() {
return text;
}
}

常见陷阱与错误示例#

1. 把枚举继续当字符串用#

如果已经定义了枚举,却还在代码里到处传 "PAID""FINISHED" 这样的字符串,就等于没真正用好枚举。

2. 依赖 ordinal() 做持久化业务值#

ordinal() 只是声明顺序下标,如果以后枚举常量顺序改了,业务值就会变,不够稳定。

3. 试图手动 new 枚举对象#

枚举对象由 Java 语言层面控制创建,不能像普通类那样手动 new

面试高频问题#

1. 枚举类和普通常量相比有什么优势#

枚举有类型约束、语义更清晰、编译期更安全,还能挂字段和方法,表达能力比字符串常量或整数常量更强。

2. 为什么说枚举本质上也是类#

因为枚举可以有字段、方法、构造方法,也能实现接口,只是它的实例数量被限制为固定几个常量对象。

3. 为什么不建议用 ordinal() 表示业务状态值#

因为它依赖声明顺序,一旦枚举顺序调整,原有业务值就可能错位。

一句话总结#

枚举类适合表达“取值有限且语义固定”的数据,比字符串常量更安全、也更容易维护。

文章目录

文章目录