在switch语句中,为什么所有的情况都被执行了?

时间:2011-11-09 00:33:04

标签: java switch-statement

我的代码中包含switch语句,我从post获得了它,并且它的工作非常正常:

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<sup>ndrdth</sup>时,会打印2。我尝试将构建器更改为缓冲区,但我得到了相同的响应......这可能是一个错误还是我犯了一些错误?

8 个答案:

答案 0 :(得分:41)

这是您代码中的错误。您忘记在每个break之后输入case

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;
}

答案 1 :(得分:22)

我在这里看不到任何错误,至少不是语言的工作方式。根据设计,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项操作。

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

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块内,但它也结束了整个方法的执行。

答案 2 :(得分:9)

你需要在每个开关案例中添加一个'break'语句。 以前工作过,因为你从方法中返回了......

答案 3 :(得分:6)

“休息”;语句将案例彼此分开,因此为了在特定情况下执行语句,只要在案件结束时立即打破案件。

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

答案 4 :(得分:3)

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

答案 5 :(得分:1)

幸运的是 switch statements on Java 12 的引入也引入了

<块引用>

“箭头案例”标签,消除了对 break 语句的需要 防止坠落 (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";
    };
}

答案 6 :(得分:0)

我看到这个问题已有8年历史了,但是这个答案应该可以帮助登录此页面的任何人。

首先让我们了解切换案例的工作方式。在C,C ++,Java,JavaScript和PHP中,在执行switch语句的同时,将执行满足满意条件的所有情况,这与仅执行选定情况的Go语言不同。 例如:

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);
   }
}

答案 7 :(得分:0)

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