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 中常量定义的首选方式。
相关推荐
愤怒的代码1 小时前
Java 面试 100 题深度解析 · 专栏总览与大纲
java·面试
银迢迢1 小时前
idea控制台中文乱码采用好几种方法一直解决不了
java·ide·intellij-idea
悦悦子a啊1 小时前
将学生管理系统改造为C/S模式 - 开发过程报告
java·开发语言·算法
步步为营DotNet1 小时前
深度解析C# 11的Required成员:编译期验证保障数据完整性
java·前端·c#
我命由我123451 小时前
开发中的英语积累 P19:Inspect、Hint、Feedback、Direction、Compact、Vulnerability
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
han_hanker2 小时前
泛型的基本语法
java·开发语言
vx_bisheyuange2 小时前
基于SpringBoot的社区养老服务系统
java·spring boot·后端·毕业设计
廋到被风吹走2 小时前
【Java】Exception 异常体系解析 从原理到实践
java·开发语言
谷哥的小弟2 小时前
Spring Framework源码解析——GenericTypeResolver
java·spring·源码