【问题标题】:In a switch statement, why are all the cases being executed?在switch语句中,为什么所有的case都被执行了?
【发布时间】:2020-09-05 17:59:20
【问题描述】:

我从post 获得了带有switch 语句的这段代码,它工作得非常好:

String getOrdinal(final int day) {
    if (day >= 11 && day <= 13) {
        return "th";
    }
    switch (day % 10) {
        case 1: return "st";
        case 2: return "nd";
        case 3: return "rd";
        default: return "th";
    }
}

但是,如果我将其更改为以下内容,它就会中断,因为除了 case 1 之外的所有情况都会被执行:

  static String getOrdinal(final int day) {
    StringBuilder ordinalBuilder = new StringBuilder();
    ordinalBuilder.append("<sup>");
    if (day >= 11 && day <= 13) {
        ordinalBuilder.append("th") ;
    }
    switch (day % 10) {
        case 1: ordinalBuilder.append("st");
        case 2: ordinalBuilder.append("nd");
        case 3: ordinalBuilder.append("rd");
        default: ordinalBuilder.append("th");
    }
    ordinalBuilder.append("</sup>");
   return ordinalBuilder.toString();
 }

当我传入2 时,这将打印2&lt;sup&gt;ndrdth&lt;/sup&gt;。我尝试将构建器更改为缓冲区,但我得到了相同的响应......这可能是一个错误还是我犯了一些错误?

【问题讨论】:

  • 内联 switch 语句没有任何好处,您应该将 getOrdinal 方法分开并让您的代码调用它。尝试将 11、12 或 13 传递给您的代码。您还创建了另一个错误。
  • 我希望我能给@TimBender 更多的 +1。这个问题就是货物崇拜编程的定义。

标签: java switch-statement


【解决方案1】:

幸好还介绍了switch statements on Java 12

“箭头大小写”标签消除了对中断语句的需要 防止跌倒 (source)。

因此,您的代码的 现代 版本如下所示:

String getOrdinal(final int day) {
    if (day >= 11 && day <= 13) {
        return "th";
    }
    return switch (day % 10) {
        case 1 -> "st";
        case 2 -> "nd";
        case 3 ->  "rd";
        default ->  "th";
    };
}

【讨论】:

    【解决方案2】:

    在每种情况下,在每一行的末尾添加一个 break 语句,或者只使用 return 语句。

    【讨论】:

      【解决方案3】:

      我看到这个问题已经超过 8 年了,但是这个答案应该可以帮助任何人登陆这个页面。

      首先让我们了解一下 switch case 的工作原理。在 C、C++、Java、JavaScript 和 PHP 中,当执行 switch 语句时,所有符合条件的 case 都会被执行,这与 Go 中只执行选定的 case 不同。 例如:

      public class Main
      {
          public static void main(String[] args) {
              int day = 11;
              switch (day % 10) {
                  case 1: System.out.println("st"); 
                  case 2: System.out.println("nd");
                  case 3: System.out.println("rd");
                  default: System.out.println("th");
              }
          }
      }
      

      目前,day 的值设置为 11,因此第一个案例满足条件,因此将执行以下所有案例。输出应如下所示:

      st                                                                                                                                                                           
      nd                                                                                                                                                                           
      rd                                                                                                                                                                           
      th 
      

      现在让我们将day 的值更改为 13,导致第三种情况满足条件,因此得到以下输出:

      rd
      th
      

      因此,如果您想在找到第一个满意的案例后破解代码,请将break; 条件放在最后。在问题return; 中提到的代码中,完成了破解代码的工作。

      此外,大多数 Java 新手程序员认为 SWITCH 语句是 IF 语句的语法糖,程序员不必重复提及条件。但情况并非如此,因为 IF 意味着在执行令人满意的条件后退出,而 SWITCH 仍继续执行。

      开关盒可以用来达到下面例子中提到的目的:
      其中
      A级“优秀!”应该打印
      对于 B 级和 C 级,应打印“做得好”
      应打印 D 级“你通过了\n 下次努力”
      应打印 F 级“下次努力”
      如果不是有效的情况,即找到等级,则应打印“无效等级”。

      public class Test {
      
         public static void main(String args[]) {
            // char grade = args[0].charAt(0);
            char grade = 'C';
      
            switch(grade) {
               case 'A' :
                  System.out.println("Excellent!");
                  break;
               case 'B' :
               case 'C' :
                  System.out.println("Well done");
                  break;
               case 'D' :
                  System.out.println("You passed");
               case 'F' :
                  System.out.println("Try hard next time");
                  break;
               default :
                  System.out.println("Invalid grade");
            }
            System.out.println("Your grade is " + grade);
         }
      }
      

      【讨论】:

        【解决方案4】:

        这是您的代码中的错误。你忘了在每个case 后面加上break

        switch (day % 10) {
            case 1: ordinalBuilder.append("st"); break;
            case 2: ordinalBuilder.append("nd"); break;
            case 3: ordinalBuilder.append("rd"); break;
            default: ordinalBuilder.append("th"); break;
        }
        

        【讨论】:

          【解决方案5】:

          一个“休息;”语句将案例彼此分开,因此为了在特定案例中执行语句,只需在案例结束时立即中断。

          如果你不使用break,编译器认为它可以继续执行所有的case直到程序结束。

          【讨论】:

            【解决方案6】:

            我在这里没有看到任何错误,至少在语言的工作方式上没有。根据设计,switch 语句的行为是它将开始执行与参数匹配的case 标签处的语句,然后继续执行直到块结束。所以

            switch (x) {
                case 1:
                    // do thing 1
                case 2:
                    // do thing 2
                case 3:
                    // do thing 3
                default:
                    // do nothing
            }
            

            如果x 为 2,将执行第 2 和第 3 件事,如果x 为 1,则将执行第 1、2 和 3 件事。

            要获得您可能正在寻找的行为,请以 break 结束每个 case

            switch (x) {
                case 1:
                    // do thing 1
                    break;
                case 2:
                    // do thing 2
                    break;
                case 3:
                    // do thing 3
                    break;
                default:
                    // do nothing
                    break;
            }
            

            (严格来说最后的break是不必要的,但我经常把它放在习惯上)。

            您在第一个代码示例中没有出现此问题的原因是return 就像一个超级break:它与break 具有相同的效果,即在switch 块内结束执行,但它也结束了整个方法的执行。

            【讨论】:

              【解决方案7】:

              第一个版本在 case 语句继续之前返回。第二个版本需要休息一下;声明以获得相同的行为。

              【讨论】:

                【解决方案8】:

                您需要在每个 switch 案例中添加一个“break”语句。 它以前工作过,因为您从方法返回...

                【讨论】:

                  猜你喜欢
                  • 2014-03-27
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-07-16
                  • 2017-07-07
                  • 2017-04-13
                  • 1970-01-01
                  相关资源
                  最近更新 更多