Java 枚举:enum 类型的定义与使用
Java 枚举(enum)是一种特殊的类,用于定义一组固定的常量。它比传统的静态常量更安全、功能更强大。本指南将从基础定义到高级应用,逐步讲解如何使用枚举。
1. 基础定义与使用
枚举最基本的用法是定义一组有限的选项,例如星期、季节或状态。
定义一个简单的枚举类型,用于表示一周的七天。
创建名为 Day.java 的文件,输入以下代码:
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
使用枚举时,直接通过 枚举名.常量名 的方式访问。
创建测试类 TestDay.java,输入以下代码进行测试:
public class TestDay {
public static void main(String[] args) {
// 声明一个 Day 类型的变量
Day today = Day.FRIDAY;
// 判断枚举值
if (today == Day.FRIDAY) {
System.out.println("今天是周五");
}
// 遍历所有枚举值
System.out.println("一周的所有天数:");
for (Day day : Day.values()) {
System.out.println(day);
}
}
}
运行代码,控制台将输出当前判断结果及所有枚举常量。
2. 枚举与 Switch 语句
枚举与 switch 语句配合使用,可以使代码逻辑更清晰、更易读。这比使用整数或字符串常量进行判断要安全得多,因为编译器会检查是否有遗漏的枚举值。
修改 TestDay.java,添加以下方法,根据不同日期输出计划:
public static void printPlan(Day day) {
switch (day) {
case MONDAY:
System.out.println("周一:开周会");
break;
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
System.out.println("工作日:编写代码");
break;
case FRIDAY:
System.out.println("周五:整理周报");
break;
case SATURDAY:
case SUNDAY:
System.out.println("周末:休息");
break;
}
}
调用该方法:printPlan(Day.MONDAY);。
注意:switch 表达式中直接填入枚举常量名称,无需加 Day. 前缀,也无需加引号。
3. 添加属性与构造函数
枚举本质上是一个类,因此可以包含构造函数、成员变量和方法。这允许我们将相关的数据和行为封装在枚举常量中。
定义一个 Operation 枚举,用于执行基本的四则运算。每个枚举常量都有一个对应的符号。
创建 Operation.java,输入以下代码:
public enum Operation {
// 在定义枚举常量时,必须调用构造函数
PLUS("+"),
MINUS("-"),
MULTIPLY("*"),
DIVIDE("/");
// 成员变量:存储运算符号
private final String symbol;
// 构造函数:默认为 private
Operation(String symbol) {
this.symbol = symbol;
}
// 获取符号的方法
public String getSymbol() {
return symbol;
}
}
注意:枚举常量的定义必须放在第一行,或者在最开始。当枚举包含其他成员时,常量列表必须以分号 ; 结尾。
测试该枚举:
public class TestOperation {
public static void main(String[] args) {
Operation op = Operation.PLUS;
System.out.println("运算符号是: " + op.getSymbol());
}
}
4. 抽象方法实现特定行为
枚举允许定义抽象方法,并在每个枚举常量中具体实现该方法。这是实现“策略模式”的一种极简方式。
重写 Operation.java,添加抽象方法 apply,并让每个常量实现具体的运算逻辑:
public enum Operation {
PLUS("+") {
@Override
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
@Override
public double apply(double x, double y) {
return x - y;
}
},
MULTIPLY("*") {
@Override
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
@Override
public double apply(double x, double y) {
return x / y;
}
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
// 定义抽象方法
public abstract double apply(double x, double y);
public String getSymbol() {
return symbol;
}
}
调用该方法:
public static void main(String[] args) {
double result = Operation.PLUS.apply(10, 20);
System.out.println("10 + 20 = " + result);
result = Operation.MULTIPLY.apply(5, 6);
System.out.println("5 * 6 = " + result);
}
运行代码,程序会根据枚举常量自动选择对应的具体计算逻辑。
5. 使用枚举实现单例模式
利用枚举是实现单例模式的最佳实践,因为它不仅能避免多线程同步问题,还能防止通过反射强行创建新实例。
定义一个名为 Singleton 的枚举,添加业务方法 doSomething:
public enum Singleton {
// 定义一个单例实例
INSTANCE;
// 业务方法
public void doSomething() {
System.out.println("执行单例的业务逻辑...");
}
}
使用该单例:
public class TestSingleton {
public static void main(String[] args) {
// 获取单例实例
Singleton instance = Singleton.INSTANCE;
// 调用方法
instance.doSomething();
}
}
分析:JVM 保证了枚举实例的唯一性,且加载机制本身就是线程安全的。这种方式比传统的“双重检查锁”代码更简洁、更安全。
6. 枚举集合的高效使用
Java 提供了专门针对枚举优化的集合类 EnumSet 和 EnumMap。它们的性能通常比通用的 HashSet 和 HashMap 更高。
6.1 EnumSet 使用
EnumSet 用于存储枚举类型的集合,内部使用位向量实现,非常高效。
创建一个包含多个工作日的集合:
import java.util.EnumSet;
public class TestEnumSet {
public static void main(String[] args) {
// 创建一个包含所有枚举值的集合
EnumSet<Day> allDays = EnumSet.allOf(Day.class);
// 创建一个包含特定枚举值的集合
EnumSet<Day> workDays = EnumSet.of(Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY, Day.THURSDAY, Day.FRIDAY);
// 创建一个范围集合 (从 MONDAY 到 FRIDAY)
EnumSet<Day> rangeDays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
System.out.println("工作日: " + workDays);
}
}
6.2 EnumMap 使用
EnumMap 的键必须是枚举类型。
创建一个映射,记录每天的计划任务:
import java.util.EnumMap;
public class TestEnumMap {
public static void main(String[] args) {
EnumMap<Day, String> taskMap = new EnumMap<>(Day.class);
taskMap.put(Day.MONDAY, "开会");
taskMap.put(Day.TUESDAY, "写代码");
taskMap.put(Day.SATURDAY, "爬山");
// 获取任务
String task = taskMap.get(Day.MONDAY);
System.out.println("周一的任务: " + task);
}
}
对比普通 HashMap 的优势:
| 特性 | EnumSet / EnumMap | HashSet / HashMap |
|---|---|---|
| 内存占用 | 极低(基于位运算或数组) | 较高(基于节点或桶) |
| 查询速度 | 极快 | 快 |
| 类型安全 | 编译期强制检查键类型 | 运行时或编译期检查 |
| 适用场景 | 键为枚举常量时 | 通用场景 |
注意:表格上方和下方必须保持空行,以确保 Markdown 解析正确。

暂无评论,快来抢沙发吧!