为什么我们需要突破案例陈述?

unj*_*nj2 92 java language-design case break switch-statement

为什么编译器不会在交换机中的每个代码块之后自动放置break语句?这是出于历史原因吗?您何时需要执行多个代码块?

Wil*_*ean 93

有时,将多个案例与相同的代码块相关联是有帮助的,例如

case 'A':
case 'B':
case 'C':
    doSomething();
    break;

case 'D':
case 'E':
    doSomethingElse();
    break;
Run Code Online (Sandbox Code Playgroud)

等等只是一个例子.

根据我的经验,通常情况下"糟透了"并且在一个案例中执行多个代码块是不好的风格,但在某些情况下可能会有用途.

  • 当你省略休息时,只需添加一条评论//"故意穿透".在我看来,这不是一个糟糕的风格,而是"容易忘记意外休息".PS当然不是在答案本身的简单情况下. (28认同)
  • @doublep:如果多个`case`以这种方式堆叠在一起,我就不会对评论感到烦恼.如果他们之间有代码,那么是的,评论可能是值得的. (6认同)
  • 我想象一种语言,你可以在一个`case`中声明多个case,就像这样:`case'A','B','C':doSomething(); case'D','E':doSomethingElse();`,不需要在case之间中断.Pascal可以这样做:"case语句将序数表达式的值与每个选择器进行比较,每个选择器可以是常量,子范围或由逗号分隔的列表." (http://wiki.freepascal.org/Case) (4认同)

Bob*_*oss 31

从历史上看,这是因为case基本上定义label,也被称为目标点一的goto电话.switch语句及其相关案例实际上只代表一个多路分支,其中有多个潜在的入口点进入代码流.

所有这一切,已经注意到几乎无限次,break几乎总是你在每个案例结束时宁愿拥有的默认行为.


Rom*_*eau 29

Java来自C,这是来自C的语法.

有时您希望多个case语句只有一个执行路径.以下是一个示例,它将告诉您一个月中的天数.

class SwitchDemo2 {
    public static void main(String[] args) {

        int month = 2;
        int year = 2000;
        int numDays = 0;

        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                numDays = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                numDays = 30;
                break;
            case 2:
                if ( ((year % 4 == 0) && !(year % 100 == 0))
                     || (year % 400 == 0) )
                    numDays = 29;
                else
                    numDays = 28;
                break;
            default:
                System.out.println("Invalid month.");
                break;
        }
        System.out.println("Number of Days = " + numDays);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 有人瞄准向上箭而错过了吗?或者也许他们有你的支撑式或压痕牛肉...... (3认同)
  • 我的学生会因为这样做而受到公开鞭打。土狼真丑啊 (2认同)
  • @ncmathsadist它说明了一种做某事的方法.我不同意这个例子可能是极端的.但它是一个真实世界的例子,我相信它可以帮助人们理解一个概念. (2认同)

Jam*_*olk 14

我认为这是一个错误.作为一种语言结构,它break与默认语言一样容易,而是有一个fallthrough关键字.我编写和阅读的大多数代码在每个案例后都有一个中断.

  • 我宁愿建议`continue <case name>`,它允许明确指定继续使用哪个case语句; (4认同)
  • @Vilx在当前`switch`中允许任意`case`时,这只是一个`goto`.;-) (4认同)

Zac*_*son 13

案例落后你可以做各种有趣的事情.

例如,假设您想要针对所有情况执行特定操作,但在某些情况下,您希望执行该操作以及其他操作.使用带有连接的switch语句会非常容易.

switch (someValue)
{
    case extendedActionValue:
        // do extended action here, falls through to normal action
    case normalActionValue:
    case otherNormalActionValue:
        // do normal action here
        break;
}
Run Code Online (Sandbox Code Playgroud)

当然,很容易忘记break案件结尾处的陈述并导致意外行为.当你省略break语句时,好的编译器会警告你.

  • @ZachJohnson,很久以后,Java 7确实允许切换字符串. (2认同)

Don*_*ows 7

为什么编译器不会在交换机中的每个代码块之后自动放置break语句?

撇开能够在几个案例中使用相同块的良好愿望(可能是特殊情况)......

这是出于历史原因吗?您何时需要执行多个代码块?

它主要是为了与C兼容,可以说是goto关键词漫游地球时的古代黑客.当然,它确实能够实现一些令人惊奇的东西,例如Duff的设备,但无论是对它有利还是反对,都是......充其量只是争论.


Nam*_*man 6

break切换之后cases的使用,以避免在开关语句下通。虽然有趣的是,这现在可以通过JEP-325实现的新形成的开关标签来实现。

通过这些更改,可以避免break使用每个开关,case如下所示:-

public class SwitchExpressionsNoFallThrough {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int value = scanner.nextInt();
        /*
         * Before JEP-325
         */
        switch (value) {
            case 1:
                System.out.println("one");
            case 2:
                System.out.println("two");
            default:
                System.out.println("many");
        }

        /*
         * After JEP-325
         */
        switch (value) {
            case 1 ->System.out.println("one");
            case 2 ->System.out.println("two");
            default ->System.out.println("many");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 JDK-12 执行上述代码时比较输出可以看作是

//input
1
// output from the implementation before JEP-325
one
two
many
// output from the implementation after JEP-325
one
Run Code Online (Sandbox Code Playgroud)

//input
2
// output from the implementation before JEP-325
two
many
// output from the implementation after JEP-325
two
Run Code Online (Sandbox Code Playgroud)

当然,事情没有改变

// input
3
many // default case match
many // branches to 'default' as well
Run Code Online (Sandbox Code Playgroud)