定义和使用枚举
声明枚举类型,使用其中的常量,并通过 values() 和 ordinal() 进行遍历
定义和使用枚举 是 CoddyKit 上的免费 Java Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。
定义和使用枚举
枚举是一种表示固定常量集合的特殊类。枚举具有类型安全、可读性强等优点,也比静态 int 常量更强大。
声明枚举
使用 enum 关键字声明枚举。每个常量都会隐式成为 public static final,并且是该枚举类型的一个实例。
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
FRIDAY, SATURDAY, SUNDAY
}
Day today = Day.WEDNESDAY;
System.out.println(today); // WEDNESDAY
System.out.println(today.name()); // WEDNESDAY
System.out.println(today.ordinal()); // 2 (zero-based index)使用 values() 迭代
EnumType.values() 按声明顺序返回所有常量。请使用它进行迭代或构建菜单。
enum Planet { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE }
for (Planet p : Planet.values()) {
System.out.println(p.ordinal() + ": " + p);
}
// 0: MERCURY
// 1: VENUS
// 2: EARTH
// ...
// Count constants
System.out.println(Planet.values().length); // 8valueOf() 与解析
Enum.valueOf(name) 会将 String 转换为匹配的常量。如果找不到匹配项,则抛出 IllegalArgumentException。
enum Status { PENDING, ACTIVE, SUSPENDED, CLOSED }
String input = "ACTIVE";
Status s = Status.valueOf(input);
System.out.println(s); // ACTIVE
try {
Status bad = Status.valueOf("UNKNOWN");
} catch (IllegalArgumentException e) {
System.out.println("Invalid status: UNKNOWN");
}
// Safe parse pattern
static Status safeFrom(String name) {
try { return Status.valueOf(name.toUpperCase()); }
catch (IllegalArgumentException e) { return Status.PENDING; }
}在 switch 中使用枚举
枚举可以完美地用于 switch 语句和表达式。现代 switch 表达式可以简洁且完整地处理枚举分支。
enum OrderStatus { CREATED, PROCESSING, SHIPPED, DELIVERED, CANCELLED }
OrderStatus status = OrderStatus.SHIPPED;
String message = switch (status) {
case CREATED -> "Order received, awaiting payment";
case PROCESSING -> "Payment confirmed, preparing shipment";
case SHIPPED -> "On the way — track your package";
case DELIVERED -> "Delivered! Enjoy your order";
case CANCELLED -> "Order cancelled";
};
System.out.println(message); // On the way — track your package使用 if/else 处理枚举
请使用 == 比较枚举常量:它们是单例实例,因此引用相等性可以正常工作。
enum UserRole { GUEST, MEMBER, ADMIN, SUPERADMIN }
UserRole role = UserRole.ADMIN;
if (role == UserRole.ADMIN || role == UserRole.SUPERADMIN) {
System.out.println("Access granted to admin panel");
} else {
System.out.println("Access denied");
}
// Enum comparison: never use .equals() for enums
// == is correct and more readable在集合中使用枚举
枚举可以存储在标准集合中。请使用 EnumSet 和 EnumMap 进行高性能的基于枚举的存储(将在后续课程中介绍)。
import java.util.*;
enum Permission { READ, WRITE, DELETE, ADMIN }
Set<Permission> userPerms = new HashSet<>();
userPerms.add(Permission.READ);
userPerms.add(Permission.WRITE);
System.out.println(userPerms.contains(Permission.DELETE)); // false
System.out.println(userPerms.contains(Permission.READ)); // true
List<Permission> allPerms = Arrays.asList(Permission.values());
System.out.println(allPerms.size()); // 4枚举实现接口
枚举可以实现接口,从而能够为每个常量附加行为,或为所有常量定义通用契约。
interface Describable {
String describe();
}
enum Season implements Describable {
SPRING, SUMMER, FALL, WINTER;
public String describe() {
return switch (this) {
case SPRING -> "Mild and rainy";
case SUMMER -> "Hot and sunny";
case FALL -> "Cool with falling leaves";
case WINTER -> "Cold and snowy";
};
}
}
for (Season s : Season.values()) {
System.out.println(s + ": " + s.describe());
}将枚举用作状态机
枚举非常适合状态机。每个常量表示一种状态,而方法定义有效的状态转换。
enum TrafficLight {
RED, YELLOW, GREEN;
public TrafficLight next() {
return switch (this) {
case RED -> GREEN;
case GREEN -> YELLOW;
case YELLOW -> RED;
};
}
}
TrafficLight light = TrafficLight.RED;
for (int i = 0; i < 6; i++) {
System.out.println(light);
light = light.next();
}
// RED, GREEN, YELLOW, RED, GREEN, YELLOW枚举最佳实践
使用枚举时请遵循以下最佳实践:
- 为常量使用全大写名称(约定)
- 为了类型安全,优先使用枚举,而不是 int 或 String 常量
- 使用 switch 表达式完整地处理所有分支
- 当常量携带数据时,为枚举添加字段和方法
实践:HTTP 状态码
一个真实场景中的枚举示例:使用工厂方法根据数字代码创建 HTTP 状态类别。
enum HttpStatus {
OK(200), CREATED(201), BAD_REQUEST(400),
UNAUTHORIZED(401), NOT_FOUND(404), SERVER_ERROR(500);
public final int code;
HttpStatus(int code) { this.code = code; }
public static HttpStatus from(int code) {
for (HttpStatus s : values())
if (s.code == code) return s;
throw new IllegalArgumentException("Unknown HTTP code: " + code);
}
public boolean isSuccess() { return code >= 200 && code < 300; }
}
HttpStatus s = HttpStatus.from(404);
System.out.println(s + " (" + s.code + ") success=" + s.isSuccess());
// NOT_FOUND (404) success=false快速检查
下面代码的输出是什么?
enum Color { RED, GREEN, BLUE }
System.out.println(Color.GREEN.ordinal());总结:定义和使用枚举
要点:
- 枚举定义一组固定的命名常量,并提供类型安全
- values() 迭代所有常量;ordinal() 返回从零开始的索引
- valueOf() 将 String 转换为匹配的常量
- 使用 ==(而不是 equals)比较枚举实例
- 枚举非常适合用于 switch 表达式,以完整地处理所有分支
- 枚举可以实现接口,为每个常量附加行为
常见问题解答
「定义和使用枚举」课时是免费的吗?
是的 — 「定义和使用枚举」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。
「定义和使用枚举」这节课中我会学到什么?
声明枚举类型,使用其中的常量,并通过 values() 和 ordinal() 进行遍历 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Java Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「定义和使用枚举」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Java Academy 课中编写并运行代码吗?
能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。