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. 单例模式天然成 → 线程安全单例
相关推荐
xcl09253 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐5 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长5 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn5 小时前
Spring 注解使用详解
java·spring
一条小小yu6 小时前
Spring IoC的理解
java·后端·spring
落魄实习生6 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈6 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白8 小时前
核心功能(Service接口)
java·mybatis
乌暮9 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习