概述
在本文中,我们将会了解到什么是 Java 枚举,枚举解决了哪些问题以及如何在实践中使用 Java 枚举实现一些设计模式。
enum 这个关键字出现在 Java5 中,它继承 java.lang.Enum 类,有关枚举更多的内容,请参考 官方文档。
以这种方式定义的常量使得代码可读性更高,允许编译时异常检查,预先记录可接受值的列表,避免由于传入无效的值引发意外情况。
下面的代码定义了一个简单快捷的枚举示例,它定义了 pizza 订单的三种状态:ORDERED、READY 、DELIVERED。
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
另外,枚举还有好多有用的方法。如果你用传统的 public static final 常量,这些方法是需要你手动写的。
自定义方法
目前为止,我们对枚举是什么以及如何使用有了基本了解。让我们在之前的例子基础上再定义一些额外的方法,让我们之前的例子更好:
public class Pizza {
private PizzaStatus status;
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
public boolean isDeliverable() {
if (getStatus() == PizzaStatus.READY) {
return true;
}
return false;
}
// Methods that set and get the status variable.
}
使用 == 运算符比较枚举类型
由于枚举类型能够确保 JVM 中仅存在一个常量的实例,因此我们可以在上述例子中使用 ==
运算符来比较两个变量。此外,==
运算符可提供编译时以及运行时的安全性。
让我们首先看下一下代码的运行时安全。其中 ==
运算符用于比较两个状态,并且如果两个值均为 null 都不会引发 NullPointerException。相反,如果使用 equals() 方法,则会抛出 NullPointerException 的异常。
if(testPz.getStatus().equals(Pizza.PizzaStatus.DELIVERED));
if(testPz.getStatus() == Pizza.PizzaStatus.DELIVERED);
至于编译时安全,我们看另外一个例子,使用 equals() 方法比较结果为 true,因为 getStatus() 方法的枚举值和另一个和另一个枚举值相同,但逻辑上应该为 false。这个问题可以通过使用 ==
运算符避免。
编译器会显示类型不兼容错误:
if(testPz.getStatus().equals(TestColor.GREEN));
if(testPz.getStatus() == TestColor.GREEN);
在 switch 语句中使用枚举类型
枚举类型同样可以被用在 switch 代码块中:
public int getDeliveryTimeInDays() {
switch (status) {
case ORDERED: return 5;
case READY: return 2;
case DELIVERED: return 0;
}
return 0;
}
枚举类型中的属性,方法,构造器
你可以在枚举类型中定义属性、方法、构造器让它功能更强大。
让我们接着拓展上面的示例,实现 pizza 从一个阶段到另一个阶段的过渡,并了解如何摆脱之前的 if 语句和 switch 语句。
public class Pizza {
private PizzaStatus status;
public enum PizzaStatus {
ORDERED (5){
@Override
public boolean isOrdered() {
return true;
}
},
READY (2){
@Override
public boolean isReady() {
return true;
}
},
DELIVERED (0){
@Override
public boolean isDelivered() {
return true;
}
};
private int timeToDelivery;
public boolean isOrdered() {
return false;}
public boolean isReady() {
return false;}
public boolean isDelivered(){
return false;}
public int getTimeToDelivery() {
return timeToDelivery;
}
PizzaStatus (int timeToDelivery) {