Java 为什么我们需要在案件陈述后休息?
为什么编译器不在开关中的每个代码块之后自动放置break语句?是历史原因吗?您希望何时执行多个代码块?编译器没有添加自动中断,因此可以使用开关/案例来测试类似Java 为什么我们需要在案件陈述后休息?,java,switch-statement,case,language-design,break,Java,Switch Statement,Case,Language Design,Break,为什么编译器不在开关中的每个代码块之后自动放置break语句?是历史原因吗?您希望何时执行多个代码块?编译器没有添加自动中断,因此可以使用开关/案例来测试类似1的条件。有时,将多个案例与同一代码块关联会很有帮助,例如 case 'A': case 'B': case 'C': doSomething(); break; case 'D': case 'E': doSomethingElse(); break; 等等,只是一个例子 根据我的经验,通常“失败”并在
1的条件。有时,将多个案例与同一代码块关联会很有帮助,例如
case 'A':
case 'B':
case 'C':
doSomething();
break;
case 'D':
case 'E':
doSomethingElse();
break;
等等,只是一个例子
根据我的经验,通常“失败”并在一个案例中执行多个代码块是一种不好的风格,但在某些情况下可能会用到它。因此,如果需要多个案例来执行相同的操作,则不必重复代码:
case THIS:
case THAT:
{
code;
break;
}
或者你可以做如下事情:
case THIS:
{
do this;
}
case THAT:
{
do that;
}
以级联方式
如果你问我的话,真的很容易出现错误/混乱。没错,因为通过一些巧妙的布局,你可以在级联中执行块。你可以用case fall-through做各种有趣的事情
例如,假设您希望对所有情况执行特定操作,但在特定情况下,您希望执行该操作加上其他操作。使用带有fall-through的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语句时,好的编译器会发出警告 因为在某些情况下,您希望流经第一个块,例如,以避免在多个块中写入相同的代码,但仍然能够将它们分割以进行mroe控制。还有很多其他原因。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
关键字。我写过和读过的大多数代码在每种情况下都会有一段中断。Java源于C,它的传统包括一种称为C的技术。
这是一种优化,它依赖于这样一个事实:在没有中断的情况下,控制从一个案例下降到下一个案例代码>语句。当C语言被标准化时,有大量类似于“在野外”的代码,如果改变语言来打破这种结构,将会适得其反
为什么编译器不在开关中的每个代码块之后自动放置break语句
撇开良好的愿望不谈,希望能够在几个情况下使用相同的块(可能是特殊情况)
是历史原因吗?您希望何时执行多个代码块
它主要是为了与C兼容,可以说是一个古老的黑客,从goto
关键字漫游地球的时代就开始了。当然,它确实实现了一些令人惊奇的事情,例如,但不管这是对它有利还是反对的观点,充其量都是有争议的。,这是因为案例
本质上定义了一个标签
,也称为转到
调用。switch语句及其关联的case实际上只是表示一个多路分支,在代码流中有多个潜在的入口点
尽管如此,人们已经注意到,break
几乎总是每个案例结束时的默认行为。根据历史记录,Tony Hoare在20世纪60年代“结构化编程”革命期间发明了案例陈述。Tony的case语句支持每个case使用多个标签,并且自动退出,而不会发出臭味break
语句。明确的
中断
要求来自BCPL/B/C行。丹尼斯·里奇(在ACM HOPL-II中)写道:
例如,语言中不存在从BCPL switchon语句转义的endcase
当我们在20世纪60年代了解到它时,因此重载break关键字来转义
从B和C转换的说法来看,这是发散的进化,而不是有意识的变化
我还没有找到任何关于BCPL的历史著作,但里奇的评论表明,
中断
或多或少是一个历史性的意外。BCPL后来解决了这个问题,但也许Ritchie和Thompson太忙于发明Unix而不关心这样一个细节:-)这是一个老问题,但事实上,我今天无意中使用了case with break语句。当您需要按顺序组合不同的函数时,不使用break实际上非常有用
e、 g.使用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;
}
}
我现在正在做一个项目,我需要在我的switch语句中使用
break
,否则代码将无法工作。请耐心听我说,我会给你一个很好的例子,说明为什么在switch语句中需要break
假设您有三种状态,一种等待用户输入数字,第二种等待用户计算数字,第三种等待用户打印总和
在这种情况下,您有:
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;
}
}
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;
}
}
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
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");
}
}
}
//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