假设我有一个包含两个可能值的枚举Color
:RED
和BLUE
public enum Color {
RED,
BLUE
}
现在假设我对这个枚举有一个switch语句,其中我有两个可能值的代码:
Color color = getColor(); // a method which returns a value of enum "Color"
switch (color) {
case RED:
...
break;
case BLUE:
...
break;
default:
break;
}
由于我为枚举的两个可能值都有代码块,所以在上面的代码中default
的用法是什么?
如果代码以某种方式到达default
块,我应该抛出异常吗?
Color color = getColor(); // a method which returns a value of enum "Color"
switch (color) {
case RED:
...
break;
case BLUE:
...
break;
default:
throw new IllegalArgumentException("This should not have happened");
}
发布于 2015-10-08 15:11:38
抛出异常是一种很好的做法,如您在第二个示例中所示。您可以通过快速失败来提高代码的可维护性。
在这种情况下,这意味着如果您以后(可能几年后)添加一个枚举值,并且它到达switch语句,您将立即发现错误。
如果未设置默认值,代码可能甚至会使用新的枚举值运行,并且可能会有不希望的行为。
发布于 2015-10-08 16:09:09
其他的答案是正确的,你应该实现一个抛出异常的default
分支,以防将来有新值添加到你的枚举中。但是,我会更进一步,质疑您为什么要首先使用switch
语句。
与C++和C#等语言不同,Java将枚举值表示为实际的对象,这意味着您可以利用面向对象编程。假设您的方法的目的是为每种颜色提供一个RGB值:
switch (color)
case RED:
return "#ff0000";
...
好吧,可以说,如果您希望每种颜色都有一个RGB值,那么您应该将其作为其描述的一部分:
public enum Color
{
RED("#FF0000"),
BLUE("#0000FF");
String rgb;
public Color(String rgb) {
this.rgb = rgb;
}
public getRgb() { return this.rgb; }
}
这样,如果你以后添加了一个新的颜色,你不得不提供一个RGB值。它甚至比其他方法的失败速度更快,因为您将在编译时而不是运行时失败。
请注意,如果需要,您可以做更复杂的事情,包括让每种颜色提供其自己的抽象方法的自定义实现。Java中的枚举非常强大,而且是面向对象的,我发现在大多数情况下,我可以避免首先在它们上使用switch
。
发布于 2015-10-08 15:14:09
切换情况的编译时完整性并不能保证运行时的完整性。
使用针对较旧版本的枚举编译的switch语句的类可以使用较新的枚举版本(具有更多值)执行。这是库依赖关系的常见情况。
由于这些原因,编译器认为不带default
的switch
用例是不完整的。
https://stackoverflow.com/questions/33019562
复制