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

发布于 2024-12-14 09:40:14 字数 1184 浏览 3 评论 0原文

我有这段代码,其中包含从 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();
 }

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

I have this code with the switch statement which I got from this post, and it works absolutely fine:

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

But if I change it to something like the following, it breaks, as all the cases besides case 1 gets executed:

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

This prints 2<sup>ndrdth</sup> when I pass in 2. I tried changing the builder to buffer but I got the same response... Could this be a bug or am I making some mistake?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

思念绕指尖 2024-12-21 09:40:14

这是你的代码中的一个错误。您忘记在每个 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;
}

It's a bug in your code. You forgot to put in a break after each 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;
}
趁微风不噪 2024-12-21 09:40:14

我在这里没有看到任何错误,至少在语言的工作方式上没有。根据设计,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 是不必要的,但我经常将其放入 out的习惯)。

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

I don't see any bug here, at least not in the way the language is working. The behavior of a switch statement, by design, is that it will start executing statements at the case label which matches the argument, and then continue until the end of the block. So

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

will do both things 2 and 3 if x is 2, and will do things 1, 2, and 3 if x is 1.

To get the behavior you're probably looking for, end each case with a 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;
}

(strictly speaking the break at the very end is unnecessary, but I often put it in out of habit).

The reason you didn't have this problem in the first code example is that return is like a super-break: it has the same effect as break, namely ending execution within the switch block, but it also ends execution of the whole method.

混吃等死 2024-12-21 09:40:14

您需要在每个 switch 情况下添加“break”语句。
它之前是有效的,因为你从方法中返回了......

you need to add a 'break' statement in every switch case.
It was worked previously because you made a return from method...

彼岸花ソ最美的依靠 2024-12-21 09:40:14

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

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

A "break;" statement separates the cases from one another so in order to execute the statements in a specific case just break the case as soon as it comes to an end.

If you don't use break the compiler thinks that it can continue execution of all the cases up to the end of the program.

逆夏时光 2024-12-21 09:40:14

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

The first version returns before continuing on in the case statement. The second version needs a break; statement to get the same behavior.

绿光 2024-12-21 09:40:14

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

首先让我们了解 switch case 的工作原理。在 C、C++、Java、JavaScript 和 PHP 中,执行 switch 语句时,会执行符合条件的 case 后的所有 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,因此第一个 case 满足条件,因此将执行以下所有 case。输出应如下所示:

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

I see this question is over 8 years old, but this answer should help anyone landing on this page.

Firstly lets's understand how switch cases work. In C, C++, Java, JavaScript, and PHP while executing switch statements all the cases following the satisfactory case are executed, unlike in Go where only selected case is executed.
For example:

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

Currently, day value is set to 11 and hence very first case satisfy the condition, and hence all below cases would be executed. The output should look like the one below:

st                                                                                                                                                                           
nd                                                                                                                                                                           
rd                                                                                                                                                                           
th 

Now let's change day value to 13 resulting in the third case to satisfy the condition and hence below output is obtained:

rd
th

Hence if you want to break the code after first satisfactory case is found then put break; condition in the end. In the code mentioned in the question return; does the job of breaking the code.

Also, most of the novice java programmers believe that SWITCH statements are syntactical sugar to IF statements wherein programmers don't have to repetitively mention conditions. But that's not the case as IF's are meant to exit after the execution of satisfactory condition while SWITCH still continues execution.

Switch cases can be utilized to achieve the purpose like one mentioned in below example:
wherein
for Grade A "Excellent!" should be printed
for Grade B and C "Well done" should be printed
for Grade D "You passed \n Try hard next time" should be printed
for Grade F "Try hard next time" should be printed
and if not a valid case i.e grade is found than "Invalid Grade" should be printed.

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);
   }
}
你在我安 2024-12-21 09:40:14

幸运的是,引入了 switch 语句Java 12里面还介绍了

“箭头大小写”标签消除了使用break语句的需要
防止失败(来源)。< /p>

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

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

Luckily with the introduction of switch statements on Java 12 which also introduced

"arrow case" labels that eliminate the need for break statements to
prevent fall through (source).

Therefore the modern version of your code looks like the following:

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";
    };
}
夕色琉璃 2024-12-21 09:40:14

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

Add a break statement at the end of the every line in each case or just use the return statement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文