4

我使用 int[] 数组作为参考。我想知道我对 case 语句的使用是否合理,或者它是否会导致错误。

这是我的代码:

    int switcheroo = intarray[0];
    int foo = intarray[1];
    boolean size = false; 
    boolean biggersize = false;

    switch (switcheroo) {

    case 0:
        switch (foo) {
        case 1:
            doSomething(switcheroo); //change switcheroo somehow.
            break;
        case 2: 
            doSomethingElse(switcheroo); //change switcheroo differently.
            break;
        }
    case 1:
        size = true;
        break;
    case 2: 
        biggersize = true;
        break;
    default:
        break;
    }

除非是巧合,否则这将按照我的意愿将嵌套 case 语句的更改影响到其他情况。

我的问题是:

这种嵌套会导致麻烦吗?

是缺少休息;在一个案例不好的做法之后?

谢谢。

编辑:在 switch 语句中间更改 switcheroo 的方法被放在那里以响应该问题。我不会这样做这是我的程序。

4

8 回答 8

8

嵌套不会完全造成麻烦,但它可能会令人困惑。添加评论和/或其他文档将真正帮助未来的编码人员(以及一周内的您自己!)通过查看它来理解这一点。

没有休息本身并不是一个坏习惯,但它是大多数情况下的陈述,所以我会在最后添加一个评论,比如// no break, allow fall-through.

因此,这两种情况都归结为良好的文档。

这些点与我不认为这段代码做你认为它会做的事情是垂直的。

case每次遇到一个子句时都不会重新评估该子句 - 它们只是跳转到切换的点。因此,在您的示例中,如果您从 开始,您将始终以- 您永远不会以from结束。case 1case 0case 2case 0

如果我要对其进行重组,这就是我要做的。而不是使用int,我会使用enum

enum Foo { GOOD_FOO, BAD_FOO }
enum Switcharoo { BAR, BAZ, BAQ, ESCAPE }
enum Size { NONE, REGULAR, BIGGER }

Foo foo = ... // assigned somewhere
Switcharoo roo = ... // assigned somewhere
Size size = NONE;

// use a while loop to reevalulate roo with each pass
while(roo != Switcharoo.ESCAPE) {
    switch(roo){
        case BAR:
                switch(foo) {
                    case GOOD_FOO: foo = doSomething(foo); break;
                    case BAD_FOO: foo = doSomethingElse(foo); break;
                }
            break;
        case BAZ:
            roo = Switcharoo.ESCAPE;
            size = Size.REGULAR;
            break;
        case BAQ:
            roo = Switcharoo.ESCAPE;
            size = Size.BIGGER;
            break;

    }
}
于 2012-07-26T15:05:53.167 回答
1

RE:是缺少休息吗?在一个案例不好的做法之后?

如果您在每个 case 语句后不包含中断,则流程将继续通过下一个语句,因此将执行多个选项的代码。

来自 Java 教程:

另一个有趣的地方是 break 语句。每个 break 语句都会终止封闭的 switch 语句。控制流继续 switch 块之后的第一条语句。break 语句是必要的,因为没有它们,switch 块中的语句就会失败:匹配 case 标签之后的所有语句都按顺序执行,无论后续 case 标签的表达式如何,直到遇到 break 语句。

检查http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html以了解有关 switch 语句的更多详细信息。

于 2012-07-26T15:05:33.993 回答
1

如果foo不是 1 也不是 2,switcheroo 应该继续case 1吗?如果是,那么您的代码是正确的。如果没有,你需要在之前添加一个breakcase 1

于 2012-07-26T15:06:04.183 回答
0

switch运算符是一种条件if运算符。并且一堆 if 运算符可能会报告您需要在代码中涉及对象多态性,而不是制作连续的 if-switch 运算符。

考虑将数据重新排列到类/对象并使用多态方法处理它们。它将使您的代码更可靠、更易于管理且更美观。

于 2012-07-26T15:08:28.313 回答
0

我不确定我是否理解您的第一个问题,您能否给我更多信息(可能是具体的)?

关于第二个问题,case后面没有break语句没有错,只要你知道代码会继续执行直到找到break语句。

于 2012-07-26T15:08:49.847 回答
0

如果只有 2 个备选方案,请选择 if/else。更少的代码行,没有break问题。

这种嵌套会导致麻烦吗?

一个问题是这样的开关嵌套很难阅读:在我注意到您使用的是嵌套开关之前,我不得不查看代码两次。这可能是一个维护问题,但这不是不使用嵌套开关的理由,只需谨慎使用它,调整缩进以阐明发生了什么,并评论使用情况。

是缺少休息;在一个案例不好的做法之后?

通过省略 break失败也会导致维护/调试问题,但我不认为这是不好的做法。毕竟,它是switch声明设计中固有的。失败的评论总是受欢迎的,这样下一个人 - 或者你,几个月后重新访问你的代码 - 知道失败是故意的。

于 2012-07-26T15:09:17.920 回答
0

好吧..看来您在这里唯一缺少的是可读性。仅当您被迫这样做时才进行这种类型的嵌套。

Is the lack of a break; after a case bad practice?

不错,而是避免异常行为是一种好习惯。如果没有此中断,您的代码将继续执行到您的最后一个案例。

在你的第一个外壳中添加 break 。

于 2012-07-26T15:10:36.540 回答
0

我建议避免结合使用嵌套和跌落。至少就个人而言,我倾向于期望每个都case以 a 结尾break,所以我只会在它很容易发现并且导致比 a 更清晰的代码的情况下使用 fallthrough if..else,例如:

switch (foo) {
    case 0:
    case 1:
        doSomething();
        break;

    case 2:
        doSomethingElse();
        break;

    default:
        break;
}

也就是说,使用空的或非常简单(一个语句)case的主体。在您的情况下,将第case一个主体重构为方法可能会起作用:

void changeSwitcheroo(int foo, int switcheroo) {
    switch (foo) {
        case 1:
            doSomething(switcheroo); //change switcheroo somehow.
            break;
        case 2: 
            doSomethingElse(switcheroo); //change switcheroo differently.
            break;
    }
}

// ...

int switcheroo = intarray[0];
int foo = intarray[1];

switch (switcheroo) {
    case 0:
        changeSwitcheroo(foo, switcheroo);
    case 1:
        size = true;
        break;
    case 2: 
        biggersize = true;
        break;
    default:
        break;
}

(这主要是在争论可读性和风格。switch的含义仍然是“如果switcheroo是1,跳转到case中间0。)

于 2012-07-26T15:23:21.357 回答