枚举类型基本上是一种数据类型,可让您以更易读和更可靠的方式描述类型的每个成员。
下面是一个简单的例子来解释原因:
假设您正在编写一个与季节有关的方法:
int 枚举模式
首先,您声明了一些 int 静态常量来表示每个季节。
public static final int SPRING = 0;
public static final int SUMMER = 1;
public static final int FALL = 2;
public static final int WINTER = 2;
然后,您声明了一个将季节名称打印到控制台的方法。
public void printSeason(int seasonCode) {
String name = "";
if (seasonCode == SPRING) {
name = "Spring";
}
else if (seasonCode == SUMMER) {
name = "Summer";
}
else if (seasonCode == FALL) {
name = "Fall";
}
else if (seasonCode == WINTER) {
name = "Winter";
}
System.out.println("It is " + name + " now!");
}
所以,在那之后,你可以像这样打印一个季节名称。
printSeason(SPRING);
printSeason(WINTER);
这是一种非常常见(但不好)的方法,可以为类中不同类型的成员做不同的事情。但是,由于这些代码涉及整数,所以你也可以这样调用方法而没有任何问题。
printSeason(0);
printSeason(1);
甚至像这样
printSeason(x - y);
printSeason(10000);
编译器不会抱怨,因为这些方法调用是有效的,你的printSeason 方法仍然可以工作。
但这里有些不对劲。 10000 的季节代码应该是什么意思?如果x - y 结果为负数怎么办?当您的方法收到一个没有意义且不应该存在的输入时,您的程序对此一无所知。
您可以解决此问题,例如,通过添加额外的检查。
...
else if (seasonCode == WINTER) {
name = "Winter";
}
else {
throw new IllegalArgumentException();
}
System.out.println(name);
现在,当季节代码无效时,程序将抛出 RunTimeException。但是,您仍然需要决定如何处理异常。
顺便说一句,你肯定注意到FALL 和WINTER 的代码都是2,对吧?
你现在应该明白了。这种模式很脆弱。它使您可以在任何地方编写条件检查。如果你正在制作一款游戏,并且想在你的想象世界中添加一个额外的赛季,那么这种模式会让你去了解所有按赛季做事的方法,并且在大多数情况下你会忘记其中的一些。
对于这种情况,您可能认为类继承是一个好主意。但我们只需要其中的一些,仅此而已。
这就是enum 发挥作用的时候。
使用enum 类型
在 Java 中,enum 类型是通过公共静态 final 字段为每个枚举常量导出一个实例的类。
在这里可以声明四个枚举常量:SPRING, SUMMER, FALL, WINTER。每个都有自己的name。
public enum Season {
SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter");
private String name;
Season(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
现在,回到方法。
public void printSeason(Season season) {
System.out.println("It is " + season.getName() + " now!");
}
您现在可以使用Season 作为输入,而不是使用int。您可以告诉Season 给您它的名称,而不是条件检查。
这就是你现在使用这个方法的方式:
printSeason(Season.SPRING);
printSeason(Season.WINTER);
printSeason(Season.WHATEVER); <-- compile error
当您使用不正确的输入时,您将收到编译时错误,并且只要程序编译,您就可以保证获得Season 的非空单例引用。
当我们需要额外的季节时,我们只需在 Season 中添加另一个常量即可。
public enum Season {
SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter"),
MYSEASON("My Season");
...
当您需要一组固定的常量时,enum 可能是一个不错的选择(但并非总是如此)。这是一个更易读、更可靠、更强大的解决方案。