break 和 switch 似乎执行所有 case 语句

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

In the latest stable release of Java and Eclipse (Kempler), entering the following code and executing it, assuming the package and class names exist:

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 语句都将被视为真,直到找到中断.这是有道理的,但我仍然想知道这背后是否还有其他原因,或者我的假设是否完全错误.

This prints the value 4. Originally, I thought it should print 2 because I thought that even if there were no break statements, each piece of code is still held in a case statement. Now I think that the issue lies in how it is compiled. For example, my current belief is that internally a boolean keeps track of whether or not a case statement was equal to the value. If it was, then the boolean is true and all case statements will be treated as true until a break is found. This makes sense, but I am still wondering if there are other reasons behind this, or if I am entirely wrong in my assumption.

推荐答案

switch之所以会这样,是因为:

The reason why switch works as it does is that this:

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

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

is really just syntactic sugar for this (basically):

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 并执行该标签后面的所有语句.

Java doesn't have a goto statement, but C does, and that's where it comes from. So if p is 2, it jumps to .L2 and executes all the statements following that label.

相关文章