Java 枚举写法(模版)

一、前言

在 Java 开发中,枚举(Enum)是一种非常重要的类型,它能有效提升代码的可读性和健壮性。本文将以 性别 为例,手把手教你如何编写规范、优雅的枚举类,并扩展多个实用方法。

二、标准枚举类结构设计

1. 基本结构模板

import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 性别枚举
 */
@Getter
@AllArgsConstructor
public enum GenderEnum {
    /**
     * 未知
     */
    UNKNOWN(0, "未知"),
    /**
     * 男
     */
    MALE(1, "男"),
    /**
     * 女
     */
    FEMALE(2, "女");

    /**
     * 性别编码
     */
    private final Integer code;
    /**
     * 描述信息
     */
    private final String desc;
}

2. 结构解析

要素 说明
@Getter 使用 Lombok 自动生成 getter 方法,避免冗余代码
@AllArgsConstructor 全参构造器,用于初始化枚举字段
final 字段 保证枚举值不可变,符合不可变对象的设计原则
注释规范 每个枚举常量添加 Javadoc 注释,描述业务含义
字段命名 code 表示原始数值编码,desc 表示中文描述

三、核心方法实现与扩展

1. 通过编码查找描述信息

/**
 * 根据编码获取描述信息
 *
 * @param code 性别编码
 * @return 对应描述信息,未找到返回空字符串
 */
public static String getDescByCode(Integer code) {
    if (code == null) {
        return StrUtil.EMPTY;
    }
    return Arrays.stream(GenderEnum.values())
            .filter(gender -> gender.getCode().equals(code))
            .findFirst()
            .map(GenderEnum::getDesc)
            .orElse(StrUtil.EMPTY);
}
代码亮点:
  • Stream API:使用 filterfindFirst 实现优雅的查找逻辑
  • 空值处理:避免因参数为 null 导致的 NPE
  • 默认值:未匹配到时返回空字符串,保证调用安全性

2. 获取所有编码与描述的 Map

/**
 * 获取所有性别编码与描述的映射
 *
 * @return 编码-描述 Map
 */
public static Map<Integer, String> getAllCodeDescMap() {
    return Arrays.stream(GenderEnum.values())
            .collect(Collectors.toMap(
                    GenderEnum::getCode,
                    GenderEnum::getDesc
            ));
}
应用场景:
  • 前后端交互时快速生成下拉选项数据
  • 数据库字段与枚举值映射校验

3. 通过编码获取枚举实例

/**
 * 根据编码获取枚举实例
 *
 * @param code 性别编码
 * @return 对应枚举实例,未找到返回 null
 */
public static GenderEnum fromCode(Integer code) {
    if (code == null) {
        return null;
    }
    return Arrays.stream(GenderEnum.values())
            .filter(gender -> gender.getCode().equals(code))
            .findFirst()
            .orElse(null);
}
注意事项:
  • 返回 null 时需在调用处做判空处理
  • 更安全的设计可抛出 IllegalArgumentException

4. 校验编码是否合法

/**
 * 校验性别编码是否合法
 *
 * @param code 待校验编码
 * @return 是否合法
 */
public static boolean isValidCode(Integer code) {
    return Arrays.stream(GenderEnum.values())
            .anyMatch(gender -> gender.getCode().equals(code));
}
使用场景:
  • 表单提交时验证参数合法性
  • 数据库字段校验前预处理

四、进阶技巧

1. 枚举与 JSON 序列化

当使用 Jackson 处理枚举时,默认会序列化为枚举名称(如 MALE)。若需序列化为中文描述:

// 在实体类字段添加注解
@JsonFormat(shape = Shape.OBJECT)
private GenderEnum gender;

或自定义序列化器:

public class EnumJsonSerializer extends JsonSerializer<GenderEnum> {
    @Override
    public void serialize(GenderEnum value, JsonGenerator gen, SerializerProvider provider) 
            throws IOException {
        gen.writeString(value.getDesc());
    }
}

2. 避免硬编码的通用方法

通过枚举方法统一管理业务逻辑,例如:

/**
 * 判断是否为女性
 */
public boolean isFemale() {
    return this == FEMALE;
}

调用示例:

if (GenderEnum.FEMALE.isFemale()) {
    // 执行女性专属逻辑
}

五、完整代码示例

import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 性别枚举
 */
@Getter
@AllArgsConstructor
public enum GenderEnum {

    UNKNOWN(0, "未知"),
    MALE(1, "男"),
    FEMALE(2, "女");

    private final Integer code;
    private final String desc;

    public static String getDescByCode(Integer code) {
        if (code == null) {
            return StrUtil.EMPTY;
        }
        return Arrays.stream(GenderEnum.values())
                .filter(gender -> gender.getCode().equals(code))
                .findFirst()
                .map(GenderEnum::getDesc)
                .orElse(StrUtil.EMPTY);
    }

    public static GenderEnum fromCode(Integer code) {
        if (code == null) {
            return null;
        }
        return Arrays.stream(GenderEnum.values())
                .filter(gender -> gender.getCode().equals(code))
                .findFirst()
                .orElse(null);
    }

    public static boolean isValidCode(Integer code) {
        return Arrays.stream(GenderEnum.values())
                .anyMatch(gender -> gender.getCode().equals(code));
    }

    public static Map<Integer, String> getAllCodeDescMap() {
        return Arrays.stream(GenderEnum.values())
                .collect(Collectors.toMap(
                        GenderEnum::getCode,
                        GenderEnum::getDesc
                ));
    }

    public boolean isFemale() {
        return this == FEMALE;
    }
}

六、总结

技术点 最佳实践建议
字段设计 使用 codedesc 保证业务扩展性
方法命名 getDescByCode 等命名需清晰表达意图
异常处理 所有方法需处理 null 和未匹配情况
Lombok 使用 合理使用 @Getter 减少样板代码
Stream API stream().anyMatch() 替代循环校验合法性
扩展方法 根据业务需求添加 isXXX() 等判断方法
文档注释 每个枚举常量添加 Javadoc 注释

你可能感兴趣的:(Java 枚举写法(模版))