← [ BACK_TO_NOTES ]

Java 枚举

enum 如何表达封闭常量集:类型安全、方法与字段、switch 与序列化边界。

#concept #growing #dev #java

[!info] related notes

Java 枚举

这个概念为什么出现

订单状态、支付渠道、权限级别是封闭且有限的集合。用 int/String 魔法值易拼错;enum 提供类型安全的常量集,并可挂行为。

[!abstract] 一句话理解 enum 是类型安全的封闭常量集合,每个常量是单例实例,可拥有字段与方法,并与 switch 良好配合。

最小可运行示例

场景:订单状态允许的合法迁移

enum OrderStatus {
    CREATED, PAID, SHIPPED, CANCELLED;

    boolean canTransitTo(OrderStatus next) {
        return switch (this) {
            case CREATED -> next == PAID || next == CANCELLED;
            case PAID -> next == SHIPPED || next == CANCELLED;
            case SHIPPED, CANCELLED -> false;
        };
    }
}

public class OrderStatusDemo {
    public static void main(String[] args) {
        System.out.println(OrderStatus.CREATED.canTransitTo(OrderStatus.PAID));
        System.out.println(OrderStatus.SHIPPED.canTransitTo(OrderStatus.PAID));
        System.out.println(OrderStatus.PAID.name());
    }
}

建议运行:

javac OrderStatusDemo.java && java OrderStatusDemo

期望输出:

true
false
PAID

结合场景再看三个关注点

  1. 比较用 == 即可(单例常量)。
  2. 状态机规则可放 enum 方法,避免散落 if。
  3. valueOf 按声明名精确匹配且区分大小写;非法名抛 IllegalArgumentException,null 抛 NPE,外部输入需明确解析策略。

核心概念与准确模型

1. 本质

  • enum 隐式继承 Enum。没有常量特定类体时隐式 final;有这类常量体时隐式 sealed,其允许子类是对应的匿名常量子类。\
  • 常量对应 public static final 字段,实例身份稳定;枚举自身的实例字段仍可变,不自动获得线程安全。\

2. 可扩展

  • 字段、构造器(private)、方法
  • 实现接口
  • 常量体覆盖方法(常量特定策略)

3. 常用 API

  • name()/ordinal()(ordinal 不适合持久化稳定契约)
  • values()/valueOf

边界情况与反直觉行为

  1. 持久化存 ordinal 后插入新常量会错位——存 name 或稳定 code 字段。
  2. Java 对象序列化按枚举声明名恢复常量,重命名会影响兼容性;JSON 映射是另一套库契约。name 稳于 ordinal,但也不是可随意改名的永久标识。\
  3. switch 表达式要求穷尽,传统 enum switch 语句不一定要求;增加常量后需重新编译并检查分支,不能把源代码穷尽检查当作所有版本组合的保证。
  4. name 返回声明名,toString 可被覆写;常量特定类体可能使 getClass 不同,判断枚举声明类型用 getDeclaringClass。\

常见误区

[!warning] 常见误区:用 ordinal 当数据库主键 顺序变化即数据腐蚀;使用显式 code。

工程实践

  1. 业务状态用 enum + 明确 code。
  2. 复杂状态机可用独立表/类,enum 保常量。
  3. JSON 映射配置枚举格式。
  4. 权限点等可用 enum 集合。

本节总结

  • enum = 类型安全封闭集
  • 可承载行为
  • 持久化用稳定标识而非 ordinal

自测题

  1. 为什么枚举常量可以用 == 比较?
  2. ordinal() 的风险是什么?
参考答案
  1. 每个常量是唯一实例(语言保证的枚举单例语义)。
  2. 声明顺序变化导致数值变化,不适合作为稳定对外契约。

延伸阅读与资料来源

资料类型支撑内容
Enum Types (Oracle Tutorial)教程enum
JLS Enum Classes规范枚举类
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本