Java枚举(Enum):定义固定值的"类型安全"利器

引言:为什么需要枚举?

想象一下,你要表示一周的七天:

  • 用数字?1=周一,2=周二... → 容易记错,不直观
  • 用字符串?"Monday" → 拼写可能出错,比较麻烦
  • 用常量?int MONDAY = 1; → 多个文件需要重复定义

这时候,枚举(Enum)就派上用场了!枚举可以让我们定义一组命名的常量,让代码更加清晰、安全。

一、什么是枚举?

枚举是一种特殊的类,它表示一组固定的常量。就像选择题的选项:

  • 星期几:周一、周二、周三...
  • 季节:春、夏、秋、冬
  • 颜色:红、绿、蓝、黄
  • 订单状态:待支付、已支付、已发货、已完成

枚举让这些选项成为类型安全的,编译器会检查你是否使用了有效的值。

二、枚举的基本使用

2.1 最简单的枚举

java 复制代码
public class BasicEnum {
    public static void main(String[] args) {
        System.out.println("=== 基本枚举使用 ===");
        
        // 定义和使用枚举
        Day today = Day.MONDAY;
        System.out.println("今天是: " + today);
        
        // 比较枚举
        Day meetingDay = Day.WEDNESDAY;
        if (today == meetingDay) {
            System.out.println("今天要开会!");
        } else {
            System.out.println("今天不开会");
        }
        
        // 使用switch语句
        System.out.println("\n=== 根据星期安排活动 ===");
        switch (today) {
            case MONDAY:
                System.out.println("周一:开始新的一周");
                break;
            case TUESDAY:
                System.out.println("周二:努力工作");
                break;
            case WEDNESDAY:
                System.out.println("周三:一周过半");
                break;
            case THURSDAY:
                System.out.println("周四:期待周末");
                break;
            case FRIDAY:
                System.out.println("周五:终于周五了");
                break;
            case SATURDAY:
            case SUNDAY:
                System.out.println("周末:好好休息");
                break;
        }
        
        // 遍历所有枚举值
        System.out.println("\n=== 一周七天 ===");
        for (Day day : Day.values()) {
            System.out.println(day);
        }
        
        // 获取枚举的序号和名称
        System.out.println("\n=== 枚举详细信息 ===");
        System.out.println(today.name());      // 名称:MONDAY
        System.out.println(today.ordinal());   // 序号:0(从0开始)
        
        // 根据名称获取枚举
        Day dayFromString = Day.valueOf("FRIDAY");
        System.out.println("从字符串获取: " + dayFromString);
    }
}

// 定义星期枚举
enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

运行结果:

java 复制代码
=== 基本枚举使用 ===
今天是: MONDAY
今天不开会

=== 根据星期安排活动 ===
周一:开始新的一周

=== 一周七天 ===
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

=== 枚举详细信息 ===
MONDAY
0
从字符串获取: FRIDAY

2.2 更多枚举示例

java 复制代码
public class MoreEnums {
    public static void main(String[] args) {
        System.out.println("=== 更多枚举示例 ===");
        
        // 颜色枚举
        Color favoriteColor = Color.BLUE;
        System.out.println("我最喜欢的颜色: " + favoriteColor);
        
        // 季节枚举
        Season currentSeason = Season.SUMMER;
        System.out.println("当前季节: " + currentSeason);
        
        // 方向枚举
        Direction direction = Direction.EAST;
        System.out.println("方向: " + direction);
        
        // 遍历枚举
        System.out.println("\n=== 所有颜色 ===");
        for (Color color : Color.values()) {
            System.out.println(color);
        }
        
        // 枚举比较
        System.out.println("\n=== 枚举比较 ===");
        Color color1 = Color.RED;
        Color color2 = Color.RED;
        Color color3 = Color.BLUE;
        
        System.out.println("color1 == color2: " + (color1 == color2));  // true
        System.out.println("color1.equals(color2): " + color1.equals(color2));  // true
        System.out.println("color1 == color3: " + (color1 == color3));  // false
        
        // 使用switch
        System.out.println("\n=== 根据颜色执行操作 ===");
        switch (favoriteColor) {
            case RED:
                System.out.println("热情的颜色");
                break;
            case GREEN:
                System.out.println("自然的颜色");
                break;
            case BLUE:
                System.out.println("冷静的颜色");
                break;
            case YELLOW:
                System.out.println("明亮的颜色");
                break;
        }
    }
}

// 颜色枚举
enum Color {
    RED, GREEN, BLUE, YELLOW, BLACK, WHITE
}

// 季节枚举
enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

// 方向枚举
enum Direction {
    NORTH, EAST, SOUTH, WEST
}

三、高级枚举:带属性的枚举

3.1 枚举可以有自己的属性和方法

java 复制代码
public class AdvancedEnum {
    public static void main(String[] args) {
        System.out.println("=== 高级枚举:带属性的枚举 ===");
        
        // 使用带属性的枚举
        Planet earth = Planet.EARTH;
        System.out.println("地球的质量: " + earth.getMass() + " kg");
        System.out.println("地球的半径: " + earth.getRadius() + " m");
        System.out.println("地球的表面重力: " + earth.surfaceGravity() + " m/s²");
        
        // 计算在不同行星上的重量
        double earthWeight = 75.0; // 75kg
        double marsWeight = earthWeight * Planet.MARS.surfaceGravity() / Planet.EARTH.surfaceGravity();
        System.out.println("75kg在地球上,在火星上是: " + marsWeight + " kg");
        
        // 显示所有行星信息
        System.out.println("\n=== 太阳系行星 ===");
        for (Planet planet : Planet.values()) {
            System.out.printf("%-10s: 质量=%e kg, 半径=%,.0f m\n",
                            planet, planet.getMass(), planet.getRadius());
        }
        
        // 测试HTTP状态码枚举
        System.out.println("\n=== HTTP状态码 ===");
        HttpStatus success = HttpStatus.OK;
        System.out.println(success.getCode() + " - " + success.getMessage());
        
        HttpStatus notFound = HttpStatus.NOT_FOUND;
        System.out.println(notFound.getCode() + " - " + notFound.getMessage());
        System.out.println("是客户端错误吗?" + notFound.isClientError());
        
        // 测试订单状态
        System.out.println("\n=== 订单状态 ===");
        OrderStatus status = OrderStatus.PROCESSING;
        System.out.println("当前状态: " + status);
        System.out.println("描述: " + status.getDescription());
        System.out.println("是否可以取消?" + status.canCancel());
        
        // 尝试转换状态
        OrderStatus nextStatus = status.next();
        if (nextStatus != null) {
            System.out.println("下一个状态: " + nextStatus);
        }
    }
}

// 行星枚举 - 带有质量和半径
enum Planet {
    // 枚举值调用构造方法
    MERCURY(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    EARTH(5.976e+24, 6.37814e6),
    MARS(6.421e+23, 3.3972e6),
    JUPITER(1.9e+27, 7.1492e7),
    SATURN(5.688e+26, 6.0268e7),
    URANUS(8.686e+25, 2.5559e7),
    NEPTUNE(1.024e+26, 2.4746e7);
    
    // 枚举的属性
    private final double mass;   // 质量(千克)
    private final double radius; // 半径(米)
    
    // 万有引力常数
    private static final double G = 6.67300E-11;
    
    // 枚举的构造方法(必须是private,可以省略不写)
    private Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    
    // Getter方法
    public double getMass() {
        return mass;
    }
    
    public double getRadius() {
        return radius;
    }
    
    // 计算方法:表面重力
    public double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    
    // 计算方法:计算重量
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

// HTTP状态码枚举
enum HttpStatus {
    // 1xx: 信息响应
    CONTINUE(100, "Continue"),
    SWITCHING_PROTOCOLS(101, "Switching Protocols"),
    
    // 2xx: 成功
    OK(200, "OK"),
    CREATED(201, "Created"),
    ACCEPTED(202, "Accepted"),
    
    // 3xx: 重定向
    MOVED_PERMANENTLY(301, "Moved Permanently"),
    FOUND(302, "Found"),
    
    // 4xx: 客户端错误
    BAD_REQUEST(400, "Bad Request"),
    UNAUTHORIZED(401, "Unauthorized"),
    FORBIDDEN(403, "Forbidden"),
    NOT_FOUND(404, "Not Found"),
    
    // 5xx: 服务器错误
    INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
    BAD_GATEWAY(502, "Bad Gateway"),
    SERVICE_UNAVAILABLE(503, "Service Unavailable");
    
    private final int code;
    private final String message;
    
    HttpStatus(int code, String message) {
        this.code = code;
        this.message = message;
    }
    
    public int getCode() {
        return code;
    }
    
    public String getMessage() {
        return message;
    }
    
    // 判断是否是信息响应
    public boolean isInformational() {
        return code >= 100 && code < 200;
    }
    
    // 判断是否是成功响应
    public boolean isSuccess() {
        return code >= 200 && code < 300;
    }
    
    // 判断是否是重定向
    public boolean isRedirection() {
        return code >= 300 && code < 400;
    }
    
    // 判断是否是客户端错误
    public boolean isClientError() {
        return code >= 400 && code < 500;
    }
    
    // 判断是否是服务器错误
    public boolean isServerError() {
        return code >= 500 && code < 600;
    }
    
    // 根据状态码获取枚举
    public static HttpStatus fromCode(int code) {
        for (HttpStatus status : values()) {
            if (status.code == code) {
                return status;
            }
        }
        return null;
    }
}

// 订单状态枚举
enum OrderStatus {
    PENDING("待支付", true) {
        @Override
        public OrderStatus next() {
            return PAID;
        }
    },
    PAID("已支付", false) {
        @Override
        public OrderStatus next() {
            return PROCESSING;
        }
    },
    PROCESSING("处理中", false) {
        @Override
        public OrderStatus next() {
            return SHIPPED;
        }
    },
    SHIPPED("已发货", false) {
        @Override
        public OrderStatus next() {
            return DELIVERED;
        }
    },
    DELIVERED("已送达", false) {
        @Override
        public OrderStatus next() {
            return COMPLETED;
        }
    },
    COMPLETED("已完成", false) {
        @Override
        public OrderStatus next() {
            return null; // 没有下一个状态
        }
    },
    CANCELLED("已取消", false) {
        @Override
        public OrderStatus next() {
            return null; // 已取消没有下一个状态
        }
    };
    
    private final String description;
    private final boolean canCancel;
    
    OrderStatus(String description, boolean canCancel) {
        this.description = description;
        this.canCancel = canCancel;
    }
    
    public String getDescription() {
        return description;
    }
    
    public boolean canCancel() {
        return canCancel;
    }
    
    // 抽象方法:每个枚举值实现自己的下一个状态
    public abstract OrderStatus next();
}

四、枚举实现接口

java 复制代码
public class EnumWithInterface {
    public static void main(String[] args) {
        System.out.println("=== 枚举实现接口 ===");
        
        // 使用计算操作枚举
        Operation add = Operation.PLUS;
        Operation subtract = Operation.MINUS;
        
        System.out.println("5 + 3 = " + add.calculate(5, 3));
        System.out.println("5 - 3 = " + subtract.calculate(5, 3));
        System.out.println("5 * 3 = " + Operation.TIMES.calculate(5, 3));
        System.out.println("6 / 3 = " + Operation.DIVIDE.calculate(6, 3));
        
        // 使用支付方式枚举
        System.out.println("\n=== 支付方式 ===");
        PaymentMethod alipay = PaymentMethod.ALIPAY;
        PaymentMethod wechat = PaymentMethod.WECHAT_PAY;
        
        alipay.pay(100.0);
        wechat.pay(200.0);
        
        System.out.println("\n=== 所有支付方式 ===");
        for (PaymentMethod method : PaymentMethod.values()) {
            System.out.println(method.getName() + " - " + method.getDescription());
        }
        
        // 使用日志级别枚举
        System.out.println("\n=== 日志系统 ===");
        LogLevel error = LogLevel.ERROR;
        LogLevel info = LogLevel.INFO;
        
        error.log("数据库连接失败");
        info.log("程序启动成功");
        
        // 根据日志级别获取颜色
        System.out.println("\n=== 日志级别颜色 ===");
        System.out.println("ERROR级别颜色: " + error.getColor());
        System.out.println("INFO级别颜色: " + info.getColor());
    }
}

// 计算接口
interface Calculator {
    double calculate(double a, double b);
}

// 计算操作枚举实现接口
enum Operation implements Calculator {
    PLUS("+") {
        @Override
        public double calculate(double a, double b) {
            return a + b;
        }
    },
    MINUS("-") {
        @Override
        public double calculate(double a, double b) {
            return a - b;
        }
    },
    TIMES("*") {
        @Override
        public double calculate(double a, double b) {
            return a * b;
        }
    },
    DIVIDE("/") {
        @Override
        public double calculate(double a, double b) {
            if (b == 0) {
                throw new ArithmeticException("除数不能为0");
            }
            return a / b;
        }
    };
    
    private final String symbol;
    
    Operation(String symbol) {
        this.symbol = symbol;
    }
    
    public String getSymbol() {
        return symbol;
    }
    
    @Override
    public String toString() {
        return symbol;
    }
}

// 支付方式枚举实现接口
enum PaymentMethod implements Payment {
    ALIPAY("支付宝", "扫码支付,方便快捷") {
        @Override
        public void pay(double amount) {
            System.out.println("使用支付宝支付: " + amount + "元");
            System.out.println("跳转到支付宝页面...");
            System.out.println("支付成功!");
        }
    },
    WECHAT_PAY("微信支付", "社交支付,红包功能") {
        @Override
        public void pay(double amount) {
            System.out.println("使用微信支付: " + amount + "元");
            System.out.println("打开微信扫一扫...");
            System.out.println("支付成功!");
        }
    },
    CREDIT_CARD("信用卡", "信用消费,分期付款") {
        @Override
        public void pay(double amount) {
            System.out.println("使用信用卡支付: " + amount + "元");
            System.out.println("请输入卡号和密码...");
            System.out.println("支付成功!");
        }
    },
    BANK_TRANSFER("银行转账", "大额支付,安全可靠") {
        @Override
        public void pay(double amount) {
            System.out.println("使用银行转账: " + amount + "元");
            System.out.println("请前往银行或使用网银...");
            System.out.println("转账成功!");
        }
    };
    
    private final String name;
    private final String description;
    
    PaymentMethod(String name, String description) {
        this.name = name;
        this.description = description;
    }
    
    public String getName() {
        return name;
    }
    
    public String getDescription() {
        return description;
    }
}

// 支付接口
interface Payment {
    void pay(double amount);
    String getName();
    String getDescription();
}

// 日志级别枚举
enum LogLevel {
    ERROR(40, "错误", "\u001B[31m") {  // 红色
        @Override
        public void log(String message) {
            System.err.println(getColor() + "[ERROR] " + message + "\u001B[0m");
        }
    },
    WARN(30, "警告", "\u001B[33m") {   // 黄色
        @Override
        public void log(String message) {
            System.out.println(getColor() + "[WARN]  " + message + "\u001B[0m");
        }
    },
    INFO(20, "信息", "\u001B[32m") {   // 绿色
        @Override
        public void log(String message) {
            System.out.println(getColor() + "[INFO]  " + message + "\u001B[0m");
        }
    },
    DEBUG(10, "调试", "\u001B[36m") {  // 青色
        @Override
        public void log(String message) {
            System.out.println(getColor() + "[DEBUG] " + message + "\u001B[0m");
        }
    };
    
    private final int level;
    private final String description;
    private final String color;
    
    LogLevel(int level, String description, String color) {
        this.level = level;
        this.description = description;
        this.color = color;
    }
    
    public int getLevel() {
        return level;
    }
    
    public String getDescription() {
        return description;
    }
    
    public String getColor() {
        return color;
    }
    
    // 抽象方法:每个日志级别有自己的日志方法
    public abstract void log(String message);
    
    // 判断是否应该记录
    public boolean shouldLog(LogLevel threshold) {
        return this.level >= threshold.level;
    }
}

五、单例模式与枚举

java 复制代码
public class SingletonEnum {
    public static void main(String[] args) {
        System.out.println("=== 枚举实现单例模式 ===");
        
        // 获取单例实例
        DatabaseConnection connection1 = DatabaseConnection.INSTANCE;
        DatabaseConnection connection2 = DatabaseConnection.INSTANCE;
        
        // 测试是否是同一个实例
        System.out.println("connection1 == connection2: " + (connection1 == connection2));
        System.out.println("connection1.equals(connection2): " + connection1.equals(connection2));
        
        // 使用单例
        connection1.connect();
        connection1.query("SELECT * FROM users");
        connection1.disconnect();
        
        // 配置文件单例
        System.out.println("\n=== 配置管理器 ===");
        ConfigManager config1 = ConfigManager.INSTANCE;
        ConfigManager config2 = ConfigManager.INSTANCE;
        
        System.out.println("config1 == config2: " + (config1 == config2));
        
        config1.set("app.name", "MyApp");
        config1.set("app.version", "1.0.0");
        
        System.out.println("app.name: " + config2.get("app.name"));
        System.out.println("app.version: " + config2.get("app.version"));
        
        // 线程池单例
        System.out.println("\n=== 线程池管理器 ===");
        ThreadPoolManager pool = ThreadPoolManager.INSTANCE;
        
        pool.execute(() -> System.out.println("任务1执行中..."));
        pool.execute(() -> System.out.println("任务2执行中..."));
        
        pool.shutdown();
    }
}

// 使用枚举实现单例模式 - 线程安全,防止反射攻击
enum DatabaseConnection {
    INSTANCE;  // 单例实例
    
    private boolean isConnected = false;
    
    // 私有构造方法(枚举的构造方法本来就是私有的)
    DatabaseConnection() {
        System.out.println("数据库连接实例创建");
        // 初始化连接
    }
    
    public void connect() {
        if (!isConnected) {
            System.out.println("连接到数据库...");
            isConnected = true;
        } else {
            System.out.println("已经连接到数据库");
        }
    }
    
    public void disconnect() {
        if (isConnected) {
            System.out.println("断开数据库连接");
            isConnected = false;
        } else {
            System.out.println("已经断开数据库连接");
        }
    }
    
    public void query(String sql) {
        if (isConnected) {
            System.out.println("执行查询: " + sql);
        } else {
            System.out.println("请先连接到数据库");
        }
    }
}

// 配置管理器单例
enum ConfigManager {
    INSTANCE;
    
    private java.util.Map<String, String> config = new java.util.HashMap<>();
    
    ConfigManager() {
        // 加载默认配置
        config.put("database.url", "jdbc:mysql://localhost:3306/mydb");
        config.put("database.username", "root");
        config.put("database.password", "password");
    }
    
    public String get(String key) {
        return config.get(key);
    }
    
    public void set(String key, String value) {
        config.put(key, value);
    }
    
    public boolean contains(String key) {
        return config.containsKey(key);
    }
    
    public void remove(String key) {
        config.remove(key);
    }
}

// 线程池管理器单例
enum ThreadPoolManager {
    INSTANCE;
    
    private java.util.concurrent.ExecutorService executor;
    
    ThreadPoolManager() {
        // 创建固定大小的线程池
        executor = java.util.concurrent.Executors.newFixedThreadPool(5);
        System.out.println("线程池创建完成");
    }
    
    public void execute(Runnable task) {
        executor.execute(task);
    }
    
    public void shutdown() {
        executor.shutdown();
        System.out.println("线程池关闭");
    }
    
    public boolean isShutdown() {
        return executor.isShutdown();
    }
}

六、枚举在实际项目中的应用

java 复制代码
import java.util.*;

public class EnumInRealWorld {
    public static void main(String[] args) {
        System.out.println("=== 枚举在实际项目中的应用 ===");
        
        // 用户权限系统
        System.out.println("\n=== 用户权限系统 ===");
        User user = new User("张三", UserRole.ADMIN);
        user.displayPermissions();
        
        // 检查权限
        System.out.println("\n=== 检查权限 ===");
        System.out.println("可以管理用户吗?" + user.canManageUsers());
        System.out.println("可以删除数据吗?" + user.canDeleteData());
        
        // 创建不同角色的用户
        User regularUser = new User("李四", UserRole.USER);
        User guest = new User("王五", UserRole.GUEST);
        
        regularUser.displayPermissions();
        guest.displayPermissions();
        
        // 订单系统
        System.out.println("\n=== 订单系统 ===");
        Order order = new Order("ORD001", 299.99);
        order.processOrder();
        
        // 模拟订单状态变化
        order.setStatus(OrderStatus2.PAID);
        order.processOrder();
        
        order.setStatus(OrderStatus2.SHIPPED);
        order.processOrder();
        
        order.setStatus(OrderStatus2.DELIVERED);
        order.processOrder();
        
        // 尝试取消已发货的订单
        boolean cancelled = order.cancel();
        System.out.println("取消订单成功?" + cancelled);
        
        // 任务调度系统
        System.out.println("\n=== 任务调度系统 ===");
        TaskScheduler scheduler = new TaskScheduler();
        
        Task task1 = new Task("备份数据库", TaskPriority.HIGH);
        Task task2 = new Task("发送邮件", TaskPriority.MEDIUM);
        Task task3 = new Task("清理日志", TaskPriority.LOW);
        
        scheduler.addTask(task1);
        scheduler.addTask(task2);
        scheduler.addTask(task3);
        
        scheduler.executeTasks();
        
        // 显示所有任务
        System.out.println("\n=== 所有任务 ===");
        scheduler.displayAllTasks();
    }
}

// 用户角色枚举
enum UserRole {
    ADMIN("管理员", 100) {
        @Override
        public List<String> getPermissions() {
            return Arrays.asList("READ", "WRITE", "DELETE", "MANAGE_USERS", "CONFIGURE_SYSTEM");
        }
    },
    USER("普通用户", 50) {
        @Override
        public List<String> getPermissions() {
            return Arrays.asList("READ", "WRITE");
        }
    },
    GUEST("访客", 10) {
        @Override
        public List<String> getPermissions() {
            return Arrays.asList("READ");
        }
    };
    
    private final String displayName;
    private final int accessLevel;
    
    UserRole(String displayName, int accessLevel) {
        this.displayName = displayName;
        this.accessLevel = accessLevel;
    }
    
    public String getDisplayName() {
        return displayName;
    }
    
    public int getAccessLevel() {
        return accessLevel;
    }
    
    // 抽象方法:每个角色有自己的权限列表
    public abstract List<String> getPermissions();
    
    // 检查具体权限
    public boolean hasPermission(String permission) {
        return getPermissions().contains(permission);
    }
    
    // 常用权限检查方法
    public boolean canRead() {
        return hasPermission("READ");
    }
    
    public boolean canWrite() {
        return hasPermission("WRITE");
    }
    
    public boolean canDelete() {
        return hasPermission("DELETE");
    }
    
    public boolean canManageUsers() {
        return hasPermission("MANAGE_USERS");
    }
}

// 用户类
class User {
    private String username;
    private UserRole role;
    
    public User(String username, UserRole role) {
        this.username = username;
        this.role = role;
    }
    
    public void displayPermissions() {
        System.out.println(username + " (" + role.getDisplayName() + ") 的权限:");
        for (String permission : role.getPermissions()) {
            System.out.println("  - " + permission);
        }
    }
    
    public boolean canManageUsers() {
        return role.canManageUsers();
    }
    
    public boolean canDeleteData() {
        return role.canDelete();
    }
    
    // Getter和Setter
    public String getUsername() { return username; }
    public UserRole getRole() { return role; }
    public void setRole(UserRole role) { this.role = role; }
}

// 订单状态枚举(另一种实现方式)
enum OrderStatus2 {
    PENDING {
        @Override
        public boolean canCancel() { return true; }
        @Override
        public OrderStatus2 next() { return PAID; }
    },
    PAID {
        @Override
        public boolean canCancel() { return true; }
        @Override
        public OrderStatus2 next() { return PROCESSING; }
    },
    PROCESSING {
        @Override
        public boolean canCancel() { return false; }
        @Override
        public OrderStatus2 next() { return SHIPPED; }
    },
    SHIPPED {
        @Override
        public boolean canCancel() { return false; }
        @Override
        public OrderStatus2 next() { return DELIVERED; }
    },
    DELIVERED {
        @Override
        public boolean canCancel() { return false; }
        @Override
        public OrderStatus2 next() { return COMPLETED; }
    },
    COMPLETED {
        @Override
        public boolean canCancel() { return false; }
        @Override
        public OrderStatus2 next() { return null; }
    },
    CANCELLED {
        @Override
        public boolean canCancel() { return false; }
        @Override
        public OrderStatus2 next() { return null; }
    };
    
    public abstract boolean canCancel();
    public abstract OrderStatus2 next();
    
    public static OrderStatus2 fromString(String status) {
        try {
            return valueOf(status.toUpperCase());
        } catch (IllegalArgumentException e) {
            return null;
        }
    }
}

// 订单类
class Order {
    private String orderId;
    private double amount;
    private OrderStatus2 status;
    
    public Order(String orderId, double amount) {
        this.orderId = orderId;
        this.amount = amount;
        this.status = OrderStatus2.PENDING;
    }
    
    public void processOrder() {
        System.out.println("\n处理订单: " + orderId);
        System.out.println("当前状态: " + status);
        System.out.println("金额: " + amount);
        
        switch (status) {
            case PENDING:
                System.out.println("等待支付...");
                break;
            case PAID:
                System.out.println("订单已支付,准备处理...");
                break;
            case PROCESSING:
                System.out.println("订单处理中...");
                break;
            case SHIPPED:
                System.out.println("订单已发货...");
                break;
            case DELIVERED:
                System.out.println("订单已送达...");
                break;
            case COMPLETED:
                System.out.println("订单已完成...");
                break;
            case CANCELLED:
                System.out.println("订单已取消...");
                break;
        }
        
        // 自动推进到下一个状态(如果可能)
        if (status.next() != null) {
            System.out.println("自动推进到下一个状态...");
            status = status.next();
        }
    }
    
    public boolean cancel() {
        if (status.canCancel()) {
            status = OrderStatus2.CANCELLED;
            System.out.println("订单 " + orderId + " 已取消");
            return true;
        } else {
            System.out.println("订单 " + orderId + " 当前状态不能取消");
            return false;
        }
    }
    
    // Getter和Setter
    public String getOrderId() { return orderId; }
    public double getAmount() { return amount; }
    public OrderStatus2 getStatus() { return status; }
    public void setStatus(OrderStatus2 status) { this.status = status; }
}

// 任务优先级枚举
enum TaskPriority {
    HIGH(1, "高", "\u001B[31m") {  // 红色
        @Override
        public void execute() {
            System.out.println(getColor() + "立即执行高优先级任务" + "\u001B[0m");
        }
    },
    MEDIUM(2, "中", "\u001B[33m") {  // 黄色
        @Override
        public void execute() {
            System.out.println(getColor() + "安排执行中优先级任务" + "\u001B[0m");
        }
    },
    LOW(3, "低", "\u001B[32m") {    // 绿色
        @Override
        public void execute() {
            System.out.println(getColor() + "空闲时执行低优先级任务" + "\u001B[0m");
        }
    };
    
    private final int level;
    private final String description;
    private final String color;
    
    TaskPriority(int level, String description, String color) {
        this.level = level;
        this.description = description;
        this.color = color;
    }
    
    public int getLevel() {
        return level;
    }
    
    public String getDescription() {
        return description;
    }
    
    public String getColor() {
        return color;
    }
    
    public abstract void execute();
    
    // 比较优先级
    public boolean isHigherThan(TaskPriority other) {
        return this.level < other.level;
    }
    
    public boolean isLowerThan(TaskPriority other) {
        return this.level > other.level;
    }
}

// 任务类
class Task {
    private String name;
    private TaskPriority priority;
    private boolean completed;
    
    public Task(String name, TaskPriority priority) {
        this.name = name;
        this.priority = priority;
        this.completed = false;
    }
    
    public void execute() {
        System.out.println("执行任务: " + name);
        priority.execute();
        completed = true;
    }
    
    public String getName() { return name; }
    public TaskPriority getPriority() { return priority; }
    public boolean isCompleted() { return completed; }
    public void setPriority(TaskPriority priority) { this.priority = priority; }
}

// 任务调度器
class TaskScheduler {
    private List<Task> tasks = new ArrayList<>();
    
    public void addTask(Task task) {
        tasks.add(task);
    }
    
    public void executeTasks() {
        // 按优先级排序(高优先级先执行)
        tasks.sort(Comparator.comparingInt(t -> t.getPriority().getLevel()));
        
        System.out.println("开始执行任务(按优先级排序):");
        for (Task task : tasks) {
            if (!task.isCompleted()) {
                task.execute();
            }
        }
    }
    
    public void displayAllTasks() {
        for (Task task : tasks) {
            System.out.println(task.getName() + " - 优先级: " + 
                             task.getPriority().getDescription() + 
                             " - 完成: " + (task.isCompleted() ? "是" : "否"));
        }
    }
}

七、总结

7.1 枚举的优势

  1. 类型安全:编译器检查枚举值是否有效
  2. 代码清晰:使用有意义的名称而不是魔法数字
  3. 易于维护:添加新枚举值不会破坏现有代码
  4. 线程安全:枚举实例是线程安全的
  5. 单例支持:天然支持单例模式

7.2 枚举的常见用途

  1. 状态表示:订单状态、任务状态、用户状态
  2. 配置选项:颜色、大小、类型
  3. 错误码:HTTP状态码、业务错误码
  4. 权限角色:用户角色、访问级别
  5. 策略模式:不同的算法策略

7.3 枚举 vs 常量

特性 枚举 常量类
类型安全 ✓ 编译器检查 ✗ 只是整数或字符串
命名空间 ✓ 有自己的命名空间 ✗ 全局命名空间
方法 ✓ 可以有方法和属性 ✗ 只是值
迭代 ✓ 可以遍历所有值 ✗ 需要手动维护列表
序列化 ✓ 内置序列化支持 ✗ 需要手动处理

7.4 枚举的最佳实践

  1. 使用有意义的名称RED 而不是 COLOR_1
  2. 添加描述信息:通过属性或方法提供更多信息
  3. 考虑使用接口:枚举可以实现接口,增加灵活性
  4. 避免过度使用:只在值固定且有限时使用枚举
  5. 使用valueOf时要小心 :可能抛出IllegalArgumentException

7.5 快速记忆口诀

  1. 枚举定义有限值 → 像选择题的选项
  2. 类型安全编译器查 → 比常量更安全
  3. 属性方法都可以有 → 不只是简单值
  4. 单例模式天然成 → 线程安全单例
相关推荐
It's now1 小时前
BeanRegistrar 的企业级应用场景及最佳实践
java·开发语言·spring
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于Java的小区物业管理系统APP的设计与实现为例,包含答辩的问题和答案
java·开发语言
会编程的林俊杰2 小时前
Mapper解析
java·mybatis
狼爷2 小时前
yyds,JDK 25 终结 import,可以像 Python 一样简单粗暴了
java
毕设源码-邱学长2 小时前
【开题答辩全过程】以 跑腿服务网站为例,包含答辩的问题和答案
java·eclipse
一 乐2 小时前
高校评教|基于SpringBoot+vue高校学生评教系统 (源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
自在极意功。2 小时前
手写Tomcat:深入理解Servlet容器工作原理
java·servlet·tomcat·socket
Boop_wu2 小时前
[Java EE] 字符流和字节流实例
java·开发语言·apache