写在开始:
1️⃣本文仅用作个人java日常开发记录学习使用,如果涉及版权或者其他问题,及时联系小编修改或者下架,多谢
2️⃣📌 摘要
本文系统梳理Java开发关于枚举Enum的核心规范,重点包含:
命名规范:强制Enum后缀+全大写常量
属性安全:final字段+私有构造
高效查询:禁止switch匹配,推荐循环/缓存方案
异常防御:Optional返回值+空值处理策略
文档标准:完整注释+变更记录
最佳实践:状态机/策略模式实现方案
禁止事项:可变状态/复杂逻辑等红线
通过本规范可提升代码健壮性和可维护性,仅供参考。
如果赶时间可以直接看第五部分:[ 五、实践案例]!
一、基础规范原则
1.1 命名规范(双严格)
// ✅ 标准格式
public enum DeviceTypeEnum {
MOBILE_PHONE,
SMART_WATCH
}
// ❌ 典型错误
public enum devicetype { // 违反驼峰命名
MobilePhone // 违反全大写
}
执行细则:
- 类名必须使用大驼峰命名法
- 必须包含Enum后缀(100%强制)
- 常量命名全大写+下划线(如HTTP_SUCCESS)
1.2 属性定义(不可变设计)
// ✅ 安全实现
private final String code;
private final String name;
// ❌ 危险实现
private String code; // 非final字段
public void setCode(){} // 存在修改入口
校验清单:
- 所有字段final修饰
- 仅允许通过构造器初始化
- 禁止提供setter方法
- 引用类型字段使用不可变集合
二、核心编码规范
1. 查找方法实现
// ✅ 推荐方案:循环匹配
public static AccessModeEnum valueOfCode(Integer code) {
for (AccessModeEnum e : values()) {
if (e.code.equals(code)) return e;
}
return null; // 或Optional.empty()
}
// ❌ 禁止方案:switch逐一匹配
public static AccessModeEnum findByCode(int code) {
switch(code) { // 新增枚举时容易遗漏,防止新加枚举导致的空指针问题。
case 1: return LAND;
case 2: return NON_LAND;
default: throw new IllegalArgumentException();
}
}
// ✅ 高级方案:静态Map缓存(适合高频调用)
private static final Map<Integer, AccessModeEnum> CODE_MAP =
Arrays.stream(values())
.collect(Collectors.toMap(AccessModeEnum::getCode, Function.identity()));
public static AccessModeEnum getByCode(Integer code) {
return CODE_MAP.get(code);
}
三、高级应用场景
//3.1 状态机引擎
public enum OrderStatusEnum {
CREATED {
@Override
public boolean canChangeTo(OrderStatusEnum newStatus) {
return newStatus == PAID || newStatus == CANCELED;
}
},
PAID {
@Override
public boolean canChangeTo(OrderStatusEnum newStatus) {
return newStatus == SHIPPED;
}
};
public abstract boolean canChangeTo(OrderStatusEnum newStatus);
}
//3.2 策略工厂
public enum FileParserEnum {
CSV(FileType.CSV) {
@Override
public Parser createParser() {
return new CsvParser();
}
},
EXCEL(FileType.XLSX) {
@Override
public Parser createParser() {
return new ExcelParser();
}
};
private final FileType fileType;
public abstract Parser createParser();
public static FileParserEnum getParser(FileType type) {
return Arrays.stream(values())
.filter(e -> e.fileType == type)
.findFirst()
.orElseThrow(() -> new UnsupportedFileTypeException(type));
}
}
public enum DiscountStrategyEnum {
VIP(amount -> amount * 0.7),
NORMAL(amount -> amount * 0.9);
private final Function<Double, Double> strategy;
DiscountStrategyEnum(Function<Double, Double> strategy) {
this.strategy = strategy;
}
public double applyDiscount(double amount) {
return strategy.apply(amount);
}
}
⚠️ 四、红线禁止清单
致命错误:
❌ 允许枚举字段被修改(非final)
❌ 使用switch处理编码映射
❌ 超过50个枚举常量未拆分
严重警告:
❌ 缺少Javadoc注释
❌ 直接返回未包装的null
❌ 在枚举中维护业务状态
优化建议:
⚠️ 避免多层嵌套枚举
⚠️ 谨慎实现接口方法
⚠️ 控制枚举方法复杂度
📝 附录:代码审查Checklist
⭐五、实践案例
@Getter
@AllArgsConstructor
public enum DownloadStatusEnum {
DOWNLOADING(1, "下载中"),
DOWNLOAD_FAIL(2, "下载失败"),
DOWNLOAD_SUCCESS(3, "下载成功");
private final Integer code;
private final String desc;
public static DownloadStatusEnum valueOfCode(Integer code) {
// 使用for循环进行匹配
for (DownloadStatusEnum index : DownloadStatusEnum.values()) {
if (Objects.equals(index.getCode(), code))
return index;
}
}
return null; // 返回null(尽量不要扔异常)
}
}
@Getter
@AllArgsConstructor
public enum OperateContentEnum {
CREATE(1, "创建"),
MODIFY(2, "修改"),
DELETE(3, "删除");
private final Integer code;
private final String name;
public static OperateContentEnum codeOf(Integer code) {
return Stream.of(values()).filter(t -> Objects.equals(code, t.getCode())).findFirst().orElse(null);
}
}
可读性
Stream API 写法更简洁,代码行数少,但对不熟悉函数式编程的人可能理解成本更高
for 循环写法更传统,大多数开发者都能立即理解
性能
对于小型枚举(几个到几十个元素),两种方法性能差异很小
对于大型枚举,for 循环可能略快,因为 Stream API 有一定的创建和操作开销
Stream API 在并行处理大量数据时有优势,但枚举通常元素较少,这一优势体现不明显
空值处理
Stream API 写法使用 Objects.equals() 可以避免 NPE
for 循环写法中的 index.getCode().equals(code) 如果 code 为 null 且 getCode() 返回基本类型的包装类可能有NPE
维护性
Stream API 写法更符合现代 Java 编程风格,更易于与其他函数式操作组合
for 循环写法更传统,但也更容易调试
建议
如果团队习惯使用 Java 8+ 特性,推荐使用 Stream API 写法
如果考虑代码的可读性和团队中可能有不熟悉 Stream API 的成员,for 循环写法更安全
最后提示:
规范不是枷锁,而是高效协作的基石! 🛠️
规范不是教条,当遇到特殊业务场景时,应在团队内讨论形成新的共识方案。
写在最后 : 码字不易,如果认为不错或者对您有帮忙,希望读者动动小手,点赞或者关注哈,多谢