Answers:
有时将多个案例与同一代码块关联会很有帮助,例如
case 'A':
case 'B':
case 'C':
doSomething();
break;
case 'D':
case 'E':
doSomethingElse();
break;
等。只是一个例子。
以我的经验来看,“跌倒”并在一种情况下执行多个代码块通常是不好的风格,但是在某些情况下可能会有用处。
// Intentional fallthrough.
略过休息时,请务必在各行之间添加注释。在我看来,这不是一个糟糕的风格,而是“容易忘记意外休息”。PS当然不是在简单的情况下,如答案本身。
case
以这种方式堆叠在一起,我不会理会注释。如果它们之间有代码,则是的,可能值得评论。
case
,就像这样:case 'A','B','C': doSomething(); case 'D','E': doSomethingElse();
,而无需在个案之间进行中断。Pascal可以做到这一点:“ case语句将序数表达式的值与每个选择器进行比较,选择器可以是常量,子范围或用逗号分隔的列表。” (wiki.freepascal.org/Case)
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);
}
}
我认为这是一个错误。作为一种语言构造,它break
与默认语言一样简单,而具有fallthrough
关键字。在每种情况下,我编写和阅读的大多数代码都会中断。
continue <case name>
它允许明确指定要继续执行的case语句;
case
在当前范围内任意时,它将switch
变成一个goto
。;-)
您可以通过大小写检查来完成各种有趣的事情。
例如,假设您要在所有情况下都执行特定的操作,但是在某些情况下,您想要执行该操作以及其他操作。使用带有掉线的switch语句将非常容易。
switch (someValue)
{
case extendedActionValue:
// do extended action here, falls through to normal action
case normalActionValue:
case otherNormalActionValue:
// do normal action here
break;
}
当然,很容易忘记break
案件结束时的陈述并引起意外行为。当您省略break语句时,好的编译器会警告您。
为什么编译器没有在开关中的每个代码块之后自动放置break语句?
抛弃了在几种情况下(可能是特殊情况)能够使用相同块的良好愿望。
是出于历史原因吗?您何时要执行多个代码块?
它主要是为了与C兼容,并且可以说是自古以来goto
关键字漫游地球时的一种古老手段。当然,它确实使一些令人惊奇的事情成为可能,例如Duff的Device,但这是赞成还是反对它的观点……充其量是有争议的。
在break
切换之后case
s的使用,以避免在开关语句下通。尽管有趣的是,现在可以通过新形成的开关标签(通过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");
}
}
}
在使用JDK-12执行上述代码时,可将比较输出视为
//input
1
// output from the implementation before JEP-325
one
two
many
// output from the implementation after JEP-325
one
和
//input
2
// output from the implementation before JEP-325
two
many
// output from the implementation after JEP-325
two
当然,事情没有改变
// input
3
many // default case match
many // branches to 'default' as well
因此,如果您需要几种情况来做同一件事,则不必重复代码:
case THIS:
case THAT:
{
code;
break;
}
或者,您可以执行以下操作:
case THIS:
{
do this;
}
case THAT:
{
do that;
}
以层叠的方式。
如果您问我,真的很容易出现错误/混乱。
do this
和do that
这只是do that
是什么?
就历史记录而言,托尼·霍尔在1960年代“结构化程序设计”革命期间发明了案例说明。Tony的case语句每个案例支持多个标签,并且没有臭味的break
语句自动退出。break
BCPL / B / C产品线提出了明确要求。丹尼斯·里奇写道(在ACM HOPL-II中):
例如,当我们在1960年代学习该语言时,从BCPL switchon语句转义的末尾不存在于该语言中,因此break关键字的重载从B和C switch语句转义是由于发散的进化而不是有意识的更改。
我尚未找到有关BCPL的任何历史著作,但Ritchie的评论暗示这break
或多或少是历史性的意外。BCPL后来解决了这个问题,但也许Ritchie和Thompson太忙于发明Unix了,所以不愿被这样的细节困扰:-)
break
可以“执行多个代码块”,并且更关心这种设计选择的动机。其他人则提到了从C到Java的著名传承,而这一答案将研究推向了C之前。我希望我们从一开始就具有这种(虽然非常原始的)模式匹配。
Java源自C,C的遗产包括称为Duff's Device的技术。这是一种优化,它依赖于以下事实:在没有break;
语句的情况下,控制权从一个案例转移到另一个案例。到C标准化时,已经有很多类似“狂野”的代码,因此更改语言以破坏这种构造可能会适得其反。
正如人们之前所说,这是允许失败,这不是一个错误,它是一个功能。如果太多的break
语句使您烦恼,则可以通过使用return
语句轻松摆脱它们。这实际上是一个好习惯,因为您的方法应尽可能小(出于可读性和可维护性的考虑),因此switch
语句对于一个方法而言已经足够大,因此,一个好的方法不应包含任何其他内容,这是一个例子:
public class SwitchTester{
private static final Log log = LogFactory.getLog(SwitchTester.class);
public static void main(String[] args){
log.info(monthsOfTheSeason(Season.WINTER));
log.info(monthsOfTheSeason(Season.SPRING));
log.info(monthsOfTheSeason(Season.SUMMER));
log.info(monthsOfTheSeason(Season.AUTUMN));
}
enum Season{WINTER, SPRING, SUMMER, AUTUMN};
static String monthsOfTheSeason(Season season){
switch(season){
case WINTER:
return "Dec, Jan, Feb";
case SPRING:
return "Mar, Apr, May";
case SUMMER:
return "Jun, Jul, Aug";
case AUTUMN:
return "Sep, Oct, Nov";
default:
//actually a NullPointerException will be thrown before reaching this
throw new IllegalArgumentException("Season must not be null");
}
}
}
执行打印:
12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb
12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May
12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug
12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov
如预期的那样。
编译器没有添加自动中断功能,因此可以使用开关/案例来测试条件,例如1 <= a <= 3
通过从1和2中删除break语句。
switch(a) {
case 1: //I'm between 1 and 3
case 2: //I'm between 1 and 3
case 3: //I'm between 1 and 3
break;
}
这是一个老问题,但实际上我今天遇到了没有中断声明的情况。当您需要按顺序组合不同的功能时,不使用break实际上非常有用。
例如,使用http响应代码通过时间令牌对用户进行身份验证
服务器响应代码401-令牌已过期->重新生成令牌并登录用户。
服务器响应代码200-令牌可以->登录用户。
在以下情况下:
case 404:
case 500:
{
Log.v("Server responses","Unable to respond due to server error");
break;
}
case 401:
{
//regenerate token
}
case 200:
{
// log in user
break;
}
使用此方法,您无需调用登录用户功能以获得401响应,因为重新生成令牌时,运行时会跳转到案例200中。
您可以轻松区分其他类型的数字,月份和计数。
如果是这种情况,那就更好了;
public static void spanishNumbers(String span){
span = span.toLowerCase().replace(" ", "");
switch (span){
case "1":
case "jan": System.out.println("uno"); break;
case "2":
case "feb": System.out.println("dos"); break;
case "3":
case "mar": System.out.println("tres"); break;
case "4":
case "apr": System.out.println("cuatro"); break;
case "5":
case "may": System.out.println("cinco"); break;
case "6":
case "jun": System.out.println("seis"); break;
case "7":
case "jul": System.out.println("seite"); break;
case "8":
case "aug": System.out.println("ocho"); break;
case "9":
case "sep": System.out.println("nueve"); break;
case "10":
case "oct": System.out.println("diez"); break;
}
}
我现在break
在我的switch语句中需要的项目上工作,否则代码将无法工作。忍受我,我会给你一个很好的例子,说明为什么break
在switch语句中需要。
假设您有三种状态,一种在等待用户输入数字,第二种在计算数字,第三种在打印总和。
在这种情况下,您可以:
查看状态,您将希望顺序从state1开始,然后是state3,最后是state2。否则,我们将仅打印用户输入而不计算总和。只是为了再次澄清一下,我们等待用户输入一个值,然后计算总和并打印总和。
这是示例代码:
while(1){
switch(state){
case state1:
// Wait for user input code
state = state3; // Jump to state3
break;
case state2:
//Print the sum code
state = state3; // Jump to state3;
case state3:
// Calculate the sum code
state = wait; // Jump to state1
break;
}
}
如果我们不使用break
它,它将按state1,state2和state3的顺序执行。但在使用break
中,我们避免这种情况,并且可以在正确的程序是开始与状态1,然后状态3和最后但并非最不重要状态2订购。
break
。