Java中的switch语句 - 默认情况 vs 显式枚举

5

我正在使用Java 6。

假设我有一个枚举类型,包含6个值,按顺序为A到F。其中大约有4个值被处理方式相同。我可以像这样编写代码:

switch (whichType) {
    case A:
    case B:
    case C:
    case D:
        return task();
    case E:
        return someothertask();
    case F:
        return anothersomeothertask();
}

或者像这样。

switch (whichType) {
    case E:
        return someothertask();
    case F:
        return anothersomeothertask();
    default:
        return task();
}

空值将永远不会到达此开关。

就简洁性和清晰度而言,第二种方法更好。从明确性的角度来看,我认为第一种方法更好。

每种方法都有其优缺点吗?

此外,这个简单问题可能是重复的,但我尝试了一下,发现还没有人问过。如果我搜索得不够好,我很抱歉。


4
你需要在枚举类中添加一个抽象方法? - Ron
2
只是为了记录:您可以在顶部、中间或任何其他位置放置default部分;它不一定要在底部。 - C. K. Young
@ChrisJester-Young 但是一些静态代码分析器禁止在非底部位置放置默认值。 - mjafari
@mjafari:如果他们有这样的任意要求,那不是我的错。:-P 我知道有些人(比如那些在他们的工具中写入这种限制的人)认为非底部的default子句是不好的风格,但我不同意,如果它能使代码更清晰,我会毫不犹豫地使用它。 - C. K. Young
5个回答

7

如果该枚举类型的值永远都是固定的六个,那么两种方式都可以。但是,如果有可能会有第七个值出现,就需要考虑一下。如果 E 和 F 是与 switch 逻辑不同的唯二异常值,而其他任何值都与 A 到 D 相同,那么可以使用 default。否则,最安全的做法是为每个值都设置一个 case


3
假设有人向枚举中添加了一个值?
在我的一些代码中,存在这种构造方式:
switch(mediaType) {
    case typeA:
    case typeB:
    case typeC:
        DoGeneric();
        break;
    case TypeD:
        DoSpecial();
        break;
}

这样做的原因是,如果有人向枚举中添加另一个可能性,在你查看使用该枚举的地方并决定在那时需要做什么之前,它不会编译。没有错过任何一点并且可以避免难以追踪的错误。


5
有人添加了 typeE 后,那段代码将会被编译。 - Stephen C
@Stephen C:根据编程语言的不同,可能会有影响(我不在Java中开发)。但是这种方式,您的代码样式工具可以检测到它,而使用“默认”则无法确定是否已被遗忘。 - Anon.

2

我倾向于使用默认值来捕获初始实现后添加的新枚举。虽然这不会产生编译时错误,但通常无法通过烟雾测试。

switch (whichType) {
    case A:
    case B:
    case C:
    case D:
        return task();
    case E:
        return someothertask();
    case F:
        return anothersomeothertask();
    default:
        throw new IllegalArgumentException("Encountered unknown type: " + whichType.name());
}

2

关于可读性,我认为第二个可能并不更清晰。例如,你的常规情况发生在特殊情况之后。

然而,我看到的真正问题是这两段代码并不完全等价。在第一种情况下,你有六个明确的情况。在第二种情况下,你有两个明确的情况和一个默认情况。这意味着,如果你的代码出现某种错误,收到了一个意外的情况,第二种情况下默认情况仍然会执行(task() 仍然会运行)。因此,这与你的第一段代码根本不同。

除此之外(决定哪个 switch 语句是正确的),我会建议选择读起来最好的那个。我个人喜欢第一个(因为它是明确的,并且留下了默认情况的空间,如果需要的话),但你必须根据自己的偏好或公司/团队的开发标准来决定。


0
如果您正在编写一些业务场景,并且希望代码能够长期存在并得到维护(由其他人员),请选择选项1。选项2没有任何问题,它简短明了,但是在谈论可维护性时,我认为选项1更胜一筹 - 特别是如果情况与某些业务逻辑相关。这将使维护工程师更容易阅读。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接