在 Java 开发中,枚举(Enum)是一种非常重要的类型,它能有效提升代码的可读性和健壮性。本文将以 性别 为例,手把手教你如何编写规范、优雅的枚举类,并扩展多个实用方法。
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;
}
要素 | 说明 |
---|---|
@Getter |
使用 Lombok 自动生成 getter 方法,避免冗余代码 |
@AllArgsConstructor |
全参构造器,用于初始化枚举字段 |
final 字段 |
保证枚举值不可变,符合不可变对象的设计原则 |
注释规范 | 每个枚举常量添加 Javadoc 注释,描述业务含义 |
字段命名 | code 表示原始数值编码,desc 表示中文描述 |
/**
* 根据编码获取描述信息
*
* @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);
}
filter
和 findFirst
实现优雅的查找逻辑/**
* 获取所有性别编码与描述的映射
*
* @return 编码-描述 Map
*/
public static Map<Integer, String> getAllCodeDescMap() {
return Arrays.stream(GenderEnum.values())
.collect(Collectors.toMap(
GenderEnum::getCode,
GenderEnum::getDesc
));
}
/**
* 根据编码获取枚举实例
*
* @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
/**
* 校验性别编码是否合法
*
* @param code 待校验编码
* @return 是否合法
*/
public static boolean isValidCode(Integer code) {
return Arrays.stream(GenderEnum.values())
.anyMatch(gender -> gender.getCode().equals(code));
}
当使用 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());
}
}
通过枚举方法统一管理业务逻辑,例如:
/**
* 判断是否为女性
*/
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;
}
}
技术点 | 最佳实践建议 |
---|---|
字段设计 | 使用 code 和 desc 保证业务扩展性 |
方法命名 | getDescByCode 等命名需清晰表达意图 |
异常处理 | 所有方法需处理 null 和未匹配情况 |
Lombok 使用 | 合理使用 @Getter 减少样板代码 |
Stream API | 用 stream().anyMatch() 替代循环校验合法性 |
扩展方法 | 根据业务需求添加 isXXX() 等判断方法 |
文档注释 | 每个枚举常量添加 Javadoc 注释 |