4

在 Java 和 Eclipse (Kempler) 的最新稳定版本中,输入以下代码并执行它,假设包名和类名存在:

package some_package;

public class what_the_heck {

    public static void main(String[] args) {
        int p = 2;
        int x = 1;
        switch(p){  
            case (1):
                x--;
            case (2):
                x = 2;
            case (3):
                x = 3;
            default:
                x++;
        }
        System.out.println(x);
    }
}

这会打印值 4。本来我认为应该打印 2,因为我认为即使没有 break 语句,每段代码仍然保存在 case 语句中。现在我认为问题在于它是如何编译的。例如,我目前的信念是,在内部,布尔值会跟踪 case 语句是否等于该值。如果是,则布尔值为真,所有 case 语句都将被视为真,直到找到中断。这是有道理的,但我仍然想知道这背后是否还有其他原因,或者我的假设是否完全错误。

4

4 回答 4

5

switch 之所以如此工作的原因是:

switch(p){  
        case (1):
            x--;
        case (2):
            x = 2;
        case (3):
            x = 3;
        default:
            x++;
    }

这实际上只是语法糖(基本上):

if (p == 1)
    goto .L1;
else if (p == 2)
    goto .L2;
else if (p == 3)
    goto .L3;
else
    goto .L4;

.L1:
    x--;
.L2:
    x = 2;
.L3:
    x = 3;
.L4:
    x++;

Java 没有goto声明,但 C 有,这就是它的来源。因此,如果p为 2,它将跳转到.L2并执行该标签后面的所有语句。

于 2013-11-05T19:16:14.863 回答
3

当您不放 abreak时,开关将执行入口点下方的所有其他情况

所以它实际上执行

 x = 2;
 x = 3;
 x++;
 print(x);
 System.out.println(x);

Tks to Pshemo here是switch语句规范的链接

于 2013-11-05T19:06:18.717 回答
1

如果 case 块中的条件为真且不存在returnor break,则所有其他 case 块都将被执行,无论是否为真。

根据经验,总是在一个case块的末尾放一个 break 或 return,你会 90% 是对的。

switch (p) {
    case (1):
        x--;
        break;
    case (2):
        x = 2;
        break;
    case (3):
        x = 3;
        break;
    default:
        x++;
        break;
}
于 2013-11-05T19:15:16.660 回答
0

如果要跳过所有后续案例,则需要break;在此案例块的最后放置一个,否则所有后续案例块也将被执行。

看看:http ://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

于 2013-11-05T19:07:00.337 回答