Java 理解开关行为

Java 理解开关行为,java,switch-statement,Java,Switch Statement,考虑以下代码 int x = 1 switch(x) { case 1: System.out.println("1"); case 2: System.out.println("2"); default: System.out.println("no value found"); } 它打印 1 2 no value found 正如预期的那样,因为在每个case语句中没有中断 我的疑问是,如果第一个案例陈述没有中断

考虑以下代码

int x = 1
switch(x) {
    case 1:
        System.out.println("1");
    case 2:
        System.out.println("2");
    default:
        System.out.println("no value found");
 }
它打印

1
2
no value found
正如预期的那样,因为在每个case语句中没有
中断

我的疑问是,如果第一个案例陈述没有中断,那么每个案例陈述如何执行
因为x不等于2,所以它的execute
case2
block

但是我理解了代码>默认一个因为没有<代码>破解< /C>程序继续执行它执行<代码>默认语句

< p>由于继承了C++的原因,执行自然进行直到切换结束或中断。没有针对遇到的情况进行测试。

开关
失败。您需要在每个下一个
案例之前添加
break
,除非您愿意

switch (x) {
    case 1:
        System.out.println("1");
        break;
    case 2:
        System.out.println("2");
        break;
    default:
        System.out.println("no value found");
}

switch语句是对的抽象,分支表也有一个隐式的fall-through,需要额外的跳转指令来避免它。也请阅读这篇文章

根据:

switch语句的主体称为switch块

如果其中一个case常量等于表达式的值,那么我们说case匹配,开关块中匹配case标签后的所有语句(如果有)都按顺序执行

如果所有这些语句正常完成,或者匹配的大小写标签后没有语句,则整个switch语句正常完成


这与如何编译和优化有关

这就是为什么一个开关比一堆链接的if语句更可取的原因。

来自:

break语句是必需的,因为如果没有它们,则 开关块失效:匹配大小写后的所有语句 标签是按顺序执行的,而不考虑 后续案例标签,直到遇到break语句


这是C编程语言的残余。在C
中,switch
比一个
goto
多一点语法糖,这取决于表达式值,因此执行只需跳到适当的
大小写
,然后继续执行。介于两者之间的标签正好是:标签。它们是跳转目标,但在其他方面不会影响控制流,并且从编译器的角度来看,标签中没有任何东西值得在其他地方跳转(除了INTERCAL的
COMEFROM
)。因此,在不想陷入其他选项的情况下,您必须在每种情况下明确地设置一个
中断

Java或多或少地继承了这些语义,同时避开了一些

另一方面,C#则更进一步,不允许完全在非空的
大小写
标签上使用fall-through

但在我看来,这有点设计错误。默认情况下,Fall-through可能更容易在编译器中实现(因为您不必在
开关的末尾添加
goto
,而且它与下面的实际工作方式非常吻合),但根据我的经验,意外使用fall-through比意外不使用fall-through导致的编程错误要多得多


在我看来,最严重的设计错误包括
switch
语句及其在现代语言中的所有怪异之处。

switch语句与
if-then-else
语句不同<代码>开关
语句具有多个执行路径

各国:

控制流继续执行开关后面的第一条语句 块中断语句是必要的,因为如果没有它们, 开关块中的语句失效:在 匹配的案例标签按顺序执行,而不考虑 后续大小写标签的表达式,直到生成break语句为止 遇到

这是正确的行为。“默认”并不意味着所有可能的答案。这意味着所有答案都没有写在案例中

int x=1
switch(x)
    {
        default:
             System.out.println("no value found");
        case 1:
            System.out.println("1");
        case 2:
            System.out.println("2");
    }
将打印

1
2
不会打印

no value found
1
2

使用休息时;语句和默认值每个值只调用一个“分支”

每个break语句终止封闭的switch语句。在遇到break语句之前,匹配大小写标签之后的所有语句都将按顺序执行,而不管后续大小写标签的表达式如何

您可以使用if-then-else,测试的开销增加了…,这在切换情况下是可以避免的,但是中断对于正确执行是必要的