1. 枚举的基本概念
1.1 为什么需要枚举?
在枚举出现之前,我们通常使用常量来表示固定值:
{
;
;
;
{
}
}
系统讲解 Java 枚举类型,包括基本语法、带属性与方法的高级用法、内置实用方法及集合类。深入探讨枚举在单例、策略及状态模式中的应用,对比枚举与常量的优劣,强调类型安全与序列化优势。最后分析枚举的局限性并提供 HTTP 状态码与配置管理的实战案例,帮助开发者提升代码质量与维护性。

在枚举出现之前,我们通常使用常量来表示固定值:
{
;
;
;
{
}
}
这种方式的问题:
// 简单的枚举定义
public enum Day {
MONDAY, // 枚举常量
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
枚举可以拥有字段、构造方法和普通方法:
public 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; // 半径(米)
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double surfaceGravity() {
return G * mass / (radius * radius);
}
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
public static final double G = 6.67300E-11;
}
枚举可以定义抽象方法和具体方法:
public enum Operation {
PLUS {
public double apply(double x, double y) {
return x + y;
}
},
MINUS {
public double apply(double x, double y) {
return x - y;
}
},
TIMES {
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE {
public double apply(double x, double y) {
return x / y;
}
};
public abstract double apply(double x, double y);
}
枚举可以实现接口,提供多态行为:
public interface Command {
void execute();
}
public enum FileOperation implements Command {
OPEN {
public void execute() {
System.out.println("打开文件");
}
},
SAVE {
public void execute() {
System.out.println("保存文件");
}
},
CLOSE {
public void execute() {
System.out.println("关闭文件");
}
};
public abstract void execute();
}
public class EnumMethods {
public static void main(String[] args) {
// 获取所有枚举值
Day[] days = Day.values();
for (Day day : days) {
System.out.println(day);
}
// 根据名称获取枚举
Day monday = Day.valueOf("MONDAY");
System.out.println(monday); // 输出:MONDAY
// 获取枚举名称和序号
System.out.println(monday.name()); // 输出:MONDAY
System.out.println(monday.ordinal()); // 输出:0(序号)
// 比较枚举
Day tuesday = Day.TUESDAY;
System.out.println(monday.compareTo(tuesday)); // 输出:-1
}
}
Java 提供了专门的枚举集合类:
public class EnumCollections {
public static void main(String[] args) {
// EnumSet - 高效的枚举集合
EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
EnumSet<Day> allDays = EnumSet.allOf(Day.class);
// EnumMap - 键为枚举的 Map
EnumMap<Day, String> activities = new EnumMap<>(Day.class);
activities.put(Day.MONDAY, "开会");
activities.put(Day.FRIDAY, "团队建设");
System.out.println(activities.get(Day.MONDAY)); // 输出:开会
}
}
枚举是实现单例的最佳方式:
public enum Singleton {
INSTANCE;
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void doSomething() {
System.out.println("单例操作:" + value);
}
}
// 使用
Singleton.INSTANCE.setValue(42);
Singleton.INSTANCE.doSomething();
public enum Calculator {
ADD {
public int calculate(int a, int b) {
return a + b;
}
},
SUBTRACT {
public int calculate(int a, int b) {
return a - b;
}
},
MULTIPLY {
public int calculate(int a, int b) {
return a * b;
}
},
DIVIDE {
public int calculate(int a, int b) {
if (b == 0) throw new ArithmeticException("除数不能为 0");
return a / b;
}
};
public abstract int calculate(int a, int b);
}
// 使用
int result = Calculator.ADD.calculate(10, 5); // 15
public enum OrderStatus {
NEW {
public OrderStatus next() {
return CONFIRMED;
}
},
CONFIRMED {
public OrderStatus next() {
return SHIPPED;
}
},
SHIPPED {
public OrderStatus next() {
return DELIVERED;
}
},
DELIVERED {
public OrderStatus next() {
return this; // 最终状态
}
};
public abstract OrderStatus next();
}
// 使用
OrderStatus status = OrderStatus.NEW;
status = status.next(); // CONFIRMED
// 不好的做法
public class Constants {
public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLUE = 3;
}
// 好的做法
public enum Color {
RED, GREEN, BLUE
}
public class TypeSafety {
// 旧方法 - 不安全
public void process(int status) {
// 可能传入非法值
}
// 新方法 - 安全
public void process(Status status) {
// 只能传入有效的枚举值
}
}
public enum Status {
ACTIVE, INACTIVE, PENDING
}
枚举的序列化是安全的,不需要担心单例破坏:
public enum SafeSerializable implements Serializable {
INSTANCE;
private int data;
public void setData(int data) {
this.data = data;
}
// 序列化安全,不需要 readResolve 方法
}
枚举不能继承其他类(已经隐式继承 Enum),但可以实现接口。
枚举实例在编译时确定,运行时不能创建新的枚举实例。
大量枚举可能会占用较多内存,但在大多数情况下这不是问题。
public enum HttpStatus {
OK(200, "OK"),
CREATED(201, "Created"),
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "Unauthorized"),
NOT_FOUND(404, "Not Found"),
INTERNAL_SERVER_ERROR(500, "Internal Server Error");
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 static HttpStatus fromCode(int code) {
for (HttpStatus status : values()) {
if (status.code == code) {
return status;
}
}
throw new IllegalArgumentException("无效的状态码:" + code);
}
public boolean isSuccess() {
return code >= 200 && code < 300;
}
public boolean isError() {
return code >= 400;
}
}
public enum AppConfig {
DATABASE_URL("db.url", "jdbc:mysql://localhost:3306/mydb"),
DATABASE_USERNAME("db.username", "root"),
DATABASE_PASSWORD("db.password", "password"),
MAX_CONNECTIONS("db.max.connections", "10"),
CACHE_ENABLED("cache.enabled", "true");
private final String key;
private final String defaultValue;
AppConfig(String key, String defaultValue) {
this.key = key;
this.defaultValue = defaultValue;
}
public String getKey() {
return key;
}
public String getDefaultValue() {
return defaultValue;
}
public String getValue() {
return System.getProperty(key, defaultValue);
}
public int getIntValue() {
return Integer.parseInt(getValue());
}
public boolean getBooleanValue() {
return Boolean.parseBoolean(getValue());
}
}
枚举是 Java 语言中一个强大而灵活的特性,正确使用枚举可以大大提高代码的质量和可维护性。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online