Java枚举类在项目中的应用

1. 枚举的本质

Java枚举是一种特殊的类,它表示一组固定常量。每个枚举常量都是枚举类的实例。

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

2. 枚举的优势

  • 类型安全:避免使用魔法数字或字符串
  • 代码可读性:使用有意义的名称
  • 编译时检查:避免无效值
  • 内置方法:values(), valueOf()等

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

1. 状态管理(最常用场景)

订单状态管理
public enum OrderStatus {
    // 定义订单状态
    CREATED("已创建", 1),
    PAID("已支付", 2),
    SHIPPED("已发货", 3),
    DELIVERED("已送达", 4),
    COMPLETED("已完成", 5),
    CANCELLED("已取消", 0);
    
    private final String description;
    private final int code;
    
    OrderStatus(String description, int code) {
        this.description = description;
        this.code = code;
    }
    
    public String getDescription() {
        return description;
    }
    
    public int getCode() {
        return code;
    }
    
    // 根据code获取枚举
    public static OrderStatus fromCode(int code) {
        for (OrderStatus status : values()) {
            if (status.code == code) {
                return status;
            }
        }
        throw new IllegalArgumentException("无效状态码: " + code);
    }
}
在业务中使用
public class Order {
    private OrderStatus status;
    
    public void cancelOrder() {
        if (status == OrderStatus.PAID || status == OrderStatus.CREATED) {
            status = OrderStatus.CANCELLED;
        } else {
            throw new IllegalStateException("当前状态不可取消订单");
        }
    }
    
    public void updateStatus(OrderStatus newStatus) {
        // 状态转换验证逻辑
        status = newStatus;
    }
}

2. 策略模式实现

支付方式处理
public enum PaymentMethod {
    ALIPAY {
        @Override
        public void processPayment(BigDecimal amount) {
            System.out.println("支付宝支付: " + amount);
            // 调用支付宝API
        }
    },
    WECHAT {
        @Override
        public void processPayment(BigDecimal amount) {
            System.out.println("微信支付: " + amount);
            // 调用微信支付API
        }
    },
    BANK_TRANSFER {
        @Override
        public void processPayment(BigDecimal amount) {
            System.out.println("银行转账: " + amount);
            // 生成银行账户信息
        }
    };
    
    public abstract void processPayment(BigDecimal amount);
}
在支付服务中使用
public class PaymentService {
    public void processOrderPayment(Order order, PaymentMethod method) {
        try {
            method.processPayment(order.getTotalAmount());
            order.setStatus(OrderStatus.PAID);
        } catch (Exception e) {
            order.setStatus(OrderStatus.PAYMENT_FAILED);
            throw new PaymentException("支付失败", e);
        }
    }
}

3. 配置管理

系统配置项
public enum SystemConfig {
    MAX_LOGIN_ATTEMPTS("security.max_login_attempts", "5"),
    SESSION_TIMEOUT("session.timeout_minutes", "30"),
    CACHE_ENABLED("cache.enabled", "true");
    
    private final String key;
    private final String defaultValue;
    
    SystemConfig(String key, String defaultValue) {
        this.key = key;
        this.defaultValue = defaultValue;
    }
    
    public String getValue() {
        // 从配置中心或配置文件中获取值
        String value = ConfigService.getProperty(key);
        return value != null ? value : defaultValue;
    }
    
    public int getIntValue() {
        return Integer.parseInt(getValue());
    }
    
    public boolean getBooleanValue() {
        return Boolean.parseBoolean(getValue());
    }
}
在业务中使用
public class LoginService {
    public void authenticate(String username, String password) {
        int maxAttempts = SystemConfig.MAX_LOGIN_ATTEMPTS.getIntValue();
        // 认证逻辑...
    }
}

4. 错误码管理

统一错误码
public enum ErrorCode {
    // 通用错误
    SUCCESS(0, "成功"),
    UNKNOWN_ERROR(1000, "未知错误"),
    INVALID_PARAM(1001, "参数无效"),
    
    // 用户相关
    USER_NOT_FOUND(2001, "用户不存在"),
    USER_DISABLED(2002, "用户已禁用"),
    
    // 订单相关
    ORDER_NOT_FOUND(3001, "订单不存在"),
    ORDER_CANCEL_FAILED(3002, "订单取消失败");
    
    private final int code;
    private final String message;
    
    ErrorCode(int code, String message) {
        this.code = code;
        this.message = message;
    }
    
    public int getCode() {
        return code;
    }
    
    public String getMessage() {
        return message;
    }
    
    public static ErrorCode fromCode(int code) {
        for (ErrorCode error : values()) {
            if (error.code == code) {
                return error;
            }
        }
        return UNKNOWN_ERROR;
    }
}
在全局异常处理中使用
@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public ResponseEntity<ErrorResponse> handleBusinessEx(BusinessException ex) {
        ErrorCode errorCode = ex.getErrorCode();
        ErrorResponse response = new ErrorResponse(
            errorCode.getCode(), 
            errorCode.getMessage(),
            ex.getAdditionalInfo()
        );
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
    }
}

public class ErrorResponse {
    private int code;
    private String message;
    private Map<String, Object> details;
    
    // 构造方法、getter等
}

5. 单例模式实现

线程安全的单例
public enum DatabaseConnection {
    INSTANCE;
    
    private Connection connection;
    
    private DatabaseConnection() {
        try {
            // 初始化数据库连接
            String url = "jdbc:mysql://localhost:3306/mydb";
            String user = "root";
            String password = "password";
            connection = DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            throw new RuntimeException("数据库连接失败", e);
        }
    }
    
    public Connection getConnection() {
        return connection;
    }
    
    public void executeQuery(String sql) {
        // 执行SQL逻辑
    }
}
在DAO层使用
public class UserDao {
    public User findById(int id) {
        Connection conn = DatabaseConnection.INSTANCE.getConnection();
        try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?")) {
            stmt.setInt(1, id);
            ResultSet rs = stmt.executeQuery();
            // 处理结果集
        } catch (SQLException e) {
            throw new DataAccessException("查询失败", e);
        }
    }
}

三、枚举的高级特性应用

1. 枚举与接口结合

状态转换接口
public interface StateTransition {
    boolean canTransitionTo(OrderStatus nextStatus);
}

public enum OrderStatus implements StateTransition {
    // 枚举常量...
    
    @Override
    public boolean canTransitionTo(OrderStatus nextStatus) {
        // 实现状态转换规则
        switch (this) {
            case CREATED:
                return nextStatus == PAID || nextStatus == CANCELLED;
            case PAID:
                return nextStatus == SHIPPED || nextStatus == CANCELLED;
            // 其他状态转换规则...
            default:
                return false;
        }
    }
}

2. 枚举与Stream API结合

动态生成下拉选项
public class EnumUtils {
    public static <E extends Enum<E>> List<Map<String, Object>> toOptionList(Class<E> enumClass) {
        return Arrays.stream(enumClass.getEnumConstants())
            .map(enumValue -> {
                Map<String, Object> option = new HashMap<>();
                option.put("value", enumValue.name());
                
                // 如果枚举实现了Descriptive接口
                if (enumValue instanceof Descriptive) {
                    option.put("label", ((Descriptive) enumValue).getDescription());
                } else {
                    option.put("label", enumValue.name());
                }
                
                return option;
            })
            .collect(Collectors.toList());
    }
}

// 前端使用
List<Map<String, Object>> statusOptions = EnumUtils.toOptionList(OrderStatus.class);

代码解析

public class EnumUtils {
1. 工具类定义
  • 定义了一个名为 EnumUtils 的公共工具类
  • 工具类通常包含静态方法,不需要实例化
public static <E extends Enum<E>> List<Map<String, Object>> toOptionList(Class<E> enumClass) {

2. 方法签名
  • public static:公共静态方法,可通过类名直接调用
  • <E extends Enum<E>>:泛型约束,确保 E 必须是枚举类型
  • List<Map<String, Object>>:返回值类型,是一个列表,每个元素是键值对集合
  • Class<E> enumClass:参数,传入一个枚举类的Class对象

作用:将枚举转换为前端可用的选项列表

    return Arrays.stream(enumClass.getEnumConstants())
3. 获取枚举值并转为流
  • enumClass.getEnumConstants():获取该枚举类的所有枚举值(实例)
  • Arrays.stream():将枚举值数组转为Java 8 Stream流,便于链式处理
        .map(enumValue -> {
            Map<String, Object> option = new HashMap<>();
4. 创建选项Map
  • map():流操作,将每个枚举值转换为新对象
  • enumValue:当前处理的枚举实例
  • new HashMap<>():创建空Map,用于存储选项数据
            option.put("value", enumValue.name());
5. 设置选项值
  • enumValue.name():获取枚举常量的名称(如 "PAID"
  • 存入Map,键为 "value",前端可通过此值识别选项
            if (enumValue instanceof Descriptive) {
                option.put("label", ((Descriptive) enumValue).getDescription());
            } else {
                option.put("label", enumValue.name());
            }
6. 智能设置显示文本
  • 检查枚举是否实现 Descriptive 接口
    • 如果实现:调用 getDescription() 获取友好名称(如 "已支付"
    • 未实现:使用枚举名称作为显示文本
  • label:前端显示用的文本

Descriptive接口示例

public interface Descriptive {
    String getDescription();
}

// 枚举实现
public enum OrderStatus implements Descriptive {
    PAID("已支付"), 
    UNPAID("未支付");
    
    private String description;
    
    OrderStatus(String desc) {
        this.description = desc;
    }
    
    @Override
    public String getDescription() {
        return description;
    }
}

            return option;
        })
7. 返回构建的选项
  • 每个枚举值转换为一个Map对象
  • Map结构:{ "value": "PAID", "label": "已支付" }
        .collect(Collectors.toList());
}

8. 收集结果
  • collect(Collectors.toList()):将流中的Map收集到List中
  • 最终返回:List<Map<String, Object>>

3. 枚举与注解结合

权限控制
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRole {
    UserRole[] value();
}

public enum UserRole {
    ADMIN, MANAGER, USER, GUEST
}

// 在服务方法上使用
public class UserService {
    @RequiresRole({UserRole.ADMIN, UserRole.MANAGER})
    public void deleteUser(int userId) {
        // 删除用户逻辑
    }
}

// 权限切面
@Aspect
@Component
public class AuthorizationAspect {
    @Before("@annotation(requiresRole)")
    public void checkRole(JoinPoint jp, RequiresRole requiresRole) {
        UserRole[] allowedRoles = requiresRole.value();
        User currentUser = SecurityContext.getCurrentUser();
        
        if (!Arrays.asList(allowedRoles).contains(currentUser.getRole())) {
            throw new AccessDeniedException("权限不足");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值