java学习--枚举(Enum)

枚举(Enum)是 Java 5 引入的一种特殊数据类型,用于定义固定数量的常量集合 (如季节、星期、颜色、状态等),相比传统的 public static final 常量,枚举更安全、可读性更高,且支持面向对象特性(方法、属性、构造器)。


一、枚举的基础定义

1. 最简枚举(无自定义属性 / 方法)

适用于仅需常量标识的场景,语法:enum 枚举名 { 常量1, 常量2, ... }

复制代码
// 定义星期枚举
public enum Weekday {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

2. 枚举的核心特性

  • 枚举类型默认继承 java.lang.Enum(无法手动继承其他类,但可实现接口);
  • 枚举常量是枚举类的实例 ,默认 public static final
  • 枚举类的构造器默认 private(无法外部实例化,保证常量唯一性);
  • 支持 switch 语句(JDK 7+ 也支持 String,但枚举更类型安全)。

二、带属性 / 方法的枚举(进阶)

枚举可像普通类一样定义属性、构造器、方法,适用于常量需要关联额外信息的场景(如状态码 + 描述)。

示例:状态枚举(含编码和描述)

复制代码
public enum OrderStatus {
    // 1. 枚举常量(需放在第一行,参数对应构造器)
    PENDING(0, "待付款"),
    PAID(1, "已付款"),
    SHIPPED(2, "已发货"),
    COMPLETED(3, "已完成"),
    CANCELLED(4, "已取消");

    // 2. 自定义属性
    private final int code;
    private final String desc;

    // 3. 私有构造器(必须private,默认也为private)
    OrderStatus(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    // 4. 普通方法(获取属性)
    public int getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }

    // 5. 静态方法(根据编码查找枚举)
    public static OrderStatus getByCode(int code) {
        for (OrderStatus status : values()) {
            if (status.code == code) {
                return status;
            }
        }
        throw new IllegalArgumentException("无效的订单状态码:" + code);
    }

    // 6. 重写方法(可选)
    @Override
    public String toString() {
        return "OrderStatus{" +
                "code=" + code +
                ", desc='" + desc + '\'' +
                '}';
    }
}

三、枚举的常用方法

java.lang.Enum 提供了核心方法,所有枚举类默认继承:

方法 作用
values() 返回枚举常量的数组(按定义顺序),用于遍历枚举
valueOf(String) 根据常量名获取枚举实例(大小写敏感,不存在则抛 IllegalArgumentException
ordinal() 返回枚举常量的索引(从 0 开始,按定义顺序)
name() 返回枚举常量的名称(与定义时一致,等同于 toString() 默认实现)

方法使用示例:

复制代码
public class EnumTest {
    public static void main(String[] args) {
        // 1. 遍历所有枚举常量
        for (OrderStatus status : OrderStatus.values()) {
            System.out.println("名称:" + status.name() + 
                               ",索引:" + status.ordinal() + 
                               ",描述:" + status.getDesc());
        }

        // 2. 根据名称获取枚举
        OrderStatus paid = OrderStatus.valueOf("PAID");
        System.out.println(paid); // 输出重写后的toString

        // 3. 自定义方法:根据编码获取枚举
        OrderStatus shipped = OrderStatus.getByCode(2);
        System.out.println(shipped.getDesc()); // 输出:已发货

        // 4. switch语句使用枚举
        OrderStatus status = OrderStatus.COMPLETED;
        switch (status) {
            case PENDING:
                System.out.println("请尽快付款");
                break;
            case COMPLETED:
                System.out.println("订单已完成");
                break;
            default:
                System.out.println("订单处理中");
        }
    }
}

四、枚举的高级用法

1. 枚举实现接口

枚举可实现接口,让不同常量有不同的行为:

复制代码
public interface Operation {
    int calculate(int a, int b);
}

public enum ArithmeticOperation implements Operation {
    ADD {
        @Override
        public int calculate(int a, int b) {
            return a + b;
        }
    },
    SUBTRACT {
        @Override
        public int calculate(int a, int b) {
            return a - b;
        }
    };
}

// 使用
System.out.println(ArithmeticOperation.ADD.calculate(5, 3)); // 8

2. 单例模式(枚举实现)

枚举是实现单例最简洁、安全的方式(天然防反射、序列化):

复制代码
public enum Singleton {
    INSTANCE; // 唯一实例

    public void doSomething() {
        System.out.println("单例方法执行");
    }
}

// 使用
Singleton.INSTANCE.doSomething();

3. 枚举集合(EnumSet/EnumMap)

Java 提供了专门的集合类优化枚举操作,性能优于普通集合:

  • EnumSet:高效存储枚举常量(内部用位运算实现);

  • EnumMap:键为枚举的 Map,性能优于 HashMap。

    // EnumSet示例
    EnumSet<Weekday> workDays = EnumSet.range(Weekday.MONDAY, Weekday.FRIDAY);
    System.out.println(workDays); // [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]

    // EnumMap示例
    EnumMap<OrderStatus, String> statusMap = new EnumMap<>(OrderStatus.class);
    statusMap.put(OrderStatus.PENDING, "待付款订单");
    System.out.println(statusMap.get(OrderStatus.PENDING)); // 待付款订单


五、枚举 vs 传统常量

特性 枚举 public static final 常量
类型安全 ✅ 编译期检查,避免传入非法值 ❌ 本质是 int/String,易传错值
可读性 ✅ 语义明确(如 OrderStatus.PAID) ❌ 需注释说明(如 1 = 已付款)
扩展性 ✅ 可添加属性 / 方法 ❌ 仅常量,无扩展能力
遍历 ✅ values () 便捷遍历 ❌ 需手动维护数组 / 集合

总结

  • 枚举适用于固定且有限的常量集合(状态、类型、选项等);
  • 基础场景用最简枚举,需关联信息用带属性的枚举;
  • 高级场景可结合接口、单例、EnumSet/EnumMap 提升扩展性和性能;
  • 枚举相比传统常量更安全、易维护,是 Java 中常量定义的首选方式。
相关推荐
莓有烦恼吖2 分钟前
基于AI图像识别与智能推荐的校园食堂评价系统研究 04-评价系统模块
java·tomcat·web·visual studio
d111111111d6 分钟前
STM32内核锁死补救方法-STM32F411CEU6
笔记·stm32·单片机·嵌入式硬件·学习
Wpa.wk7 分钟前
接口自动化 - 了解接口自动化框架RESTAssured (Java版)
java·数据库·自动化
AI架构师易筋8 分钟前
技能学习的隐形陷阱:理论过载(Theory Overload)与高效学习框架
学习
wa的一声哭了10 分钟前
内积空间 内积空间二
java·开发语言·python·spring·java-ee·django·maven
SadSunset10 分钟前
Git常用命令
java·学习
晓131310 分钟前
后端篇——第二章 Maven高级全面教程
java·maven
普兰店拉马努金11 分钟前
【高中数学/排列组合】由字母AB构成的一个6位的序列,含有连续子序列ABA的序列有多少个?
java·排列组合
cike_y13 分钟前
Spring使用注解开发
java·后端·spring·jdk1.8
好奇龙猫15 分钟前
【大学院-筆記試験練習:数据库(データベース問題訓練) と 软件工程(ソフトウェア)(5)】
学习