这篇文章由 JavaGuide 翻译,公众号: JavaGuide,原文地址:https://www.baeldung.com/a-guide-to-java-enums 。
1 引文
在本文中,我们将看到什么是 Java 枚举,它们解决了哪些问题以及如何在实践中使用 Java 枚举实现一些设计模式。
enum关键字在 java5 中引入,表示一种特殊类型的类,其总是继承java.lang.Enum类,更多内容可以自行查看其官方文档。
枚举在很多时候会和常量拿来对比,可能因为本身我们大量实际使用枚举的地方就是为了替代常量。那么这种方式有什么优势呢?
以这种方式定义的常量使代码更具可读性,允许进行编译时检查,预先记录可接受值的列表,并避免由于传入无效值而引起的意外行为。
下面示例定义一个简单的枚举类型 pizza 订单的状态,共有三种 ORDERED, READY, DELIVERED状态:
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
简单来说,我们通过上面的代码避免了定义常量,我们将所有和 pizza 订单的状态的常量都统一放到了一个枚举类型里面。
System.out.println(PizzaStatus.ORDERED.name());//ORDERED
System.out.println(PizzaStatus.ORDERED);//ORDERED
System.out.println(PizzaStatus.ORDERED.name().getClass());//class java.lang.String
System.out.println(PizzaStatus.ORDERED.getClass());
2 自定义枚举方法
现在我们对枚举是什么以及如何使用它们有了基本的了解,让我们通过在枚举上定义一些额外的API方法,将上一个示例提升到一个新的水平:
public class Pizza {
private PizzaStatus status;
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
public boolean isDeliverable() {
return getStatus() == PizzaStatus.READY;
}
// Methods that set and get the status variable.
}
3 使用 == 比较枚举类型
由于枚举类型确保JVM中仅存在一个常量实例,因此我们可以安全地使用 ==
运算符比较两个变量,如上例所示;此外,==
运算符可提供编译时和运行时的安全性。
首先,让我们看一下以下代码段中的运行时安全性,其中 ==
运算符用于比较状态,并且如果两个值均为null 都不会引发 NullPointerException。相反,如果使用equals方法,将抛出 NullPointerException:
Pizza.PizzaStatus pizza = null;
System.out.println(pizza.equals(Pizza.PizzaStatus.DELIVERED));//空指针异常
System.out.println(pizza == Pizza.PizzaStatus.DELIVERED);//正常运行
对于编译时安全性,我们看另一个示例,两个不同枚举类型进行比较:
if (Pizza.PizzaStatus.DELIVERED.equals(TestColor.GREEN)); // 编译正常
if (Pizza.PizzaStatus.DELIVERED == TestColor.GREEN); // 编译失败,类型不匹配
4 在Switch语句中使用枚举类型
public int getDeliveryTimeInDays() {
switch (status) {
case ORDERED:
return 5;
case READY:
return 2;
case DELIVERED:
return 0;
}
return 0;
}
5 枚举类型的属性、方法和构造函数
你可以通过在枚举类型中定义属性,方法和构造函数让它变得更加强大。
下面,让我们扩展上面的示例,实现从比萨的一个阶段到另一个阶段的过渡,并了解如何摆脱之前使用的if语句和switch语句:
public class Pizza {
private PizzaStatus status;
public enum PizzaStatus {
ORDERED (5){