java的break和continue语句
在任何轮回语句的主体部门,亦可用break和continue节制轮回的流程。个中,break用于强行退出轮回,不执行轮回中剩余的语句。而continue则遏制执行当前的重复,然退却回轮回起始和,开始新的重复。
下面这个措施向各人展示了break和continue在for和while轮回中的例子:
//: BreakAndContinue.java // Demonstrates break and continue keywords public class BreakAndContinue { public static void main(String[] args) { for(int i = 0; i < 100; i++) { if(i == 74) break; // Out of for loop if(i % 9 != 0) continue; // Next iteration System.out.println(i); } int i = 0; // An "infinite loop": while(true) { i++; int j = i * 27; if(j == 1269) break; // Out of loop if(i % 10 != 0) continue; // Top of loop System.out.println(i); } } } ///:~
在这个for轮回中,i的值永远不会达到100。因为一旦i达到74,break语句就会间断轮回。凡是,只有在不知道间断条件何时满意时,才需象这样利用break。只要i不能被9整除,continue语句会使措施流程返回轮回的最开头执行(所以使i值递增)。假如可以或许整除,则将值显示出来。
第二部门向各人展现了一个“无限轮回”的环境。然而,轮回内部有一个break语句,可中止轮回。除此以外,各人还会看到continue移回轮回顶部,同时不完成剩余的内容(所以只有在i值能被9整除时才打印出值)。输出功效如下:
0 9 18 27 36 45 54 63 72 10 20 30 40
之所以显示0,是由于0%9便是0。
无限轮回的第二种形式是for(;;)。编译器将while(true)与for(;;)看作同一回事。所以详细选用哪个取决于本身的编程习惯。
1. 污名昭著的“goto”
goto要害字很早就在措施设计语言中呈现。事实上,goto是汇编语言的措施节制布局的始祖:“若条件A,则跳到这里;不然跳到哪里”。若阅读由险些所有编译器生成的汇编代码,就会发明措施节制里包括了很多跳转。然而,goto是在源码的级别跳转的,所以招致了欠好的声誉。若措施老是从一个处所跳到另一个处所,尚有什么步伐能识别代码的流程呢?跟着Edsger Dijkstra著名的“Goto有害”论的问世,goto便以后失宠。
事实上,真正的问题并不在于利用goto,而在于goto的滥用。并且在一些少见的环境下,goto是组织节制流程的最佳手段。
尽量goto仍是Java的一个保存字,但并未在语言中获得正式利用;Java没有goto。然而,在break和continue这两个要害字的身上,我们仍然能看出一些goto的影子。它并不属于一次跳转,而是间断轮回语句的一种要领。之所以把它们纳入goto问题中一起接头,是由于它们利用了沟通的机制:标签。
“标签”是后头跟一个冒号的标识符,就象下面这样:
label1:
对Java来说,独一用到标签的处所是在轮回语句之前。进一步说,它实际需要紧靠在轮回语句的前方——在标签和轮回之间置入任何语句都是不明智的。而在轮回之前配置标签的独一来由是:我们但愿在个中嵌套另一个轮回可能一个开关。这是由于break和continue要害字凡是只间断当前轮回,但若伴同标签利用,它们就会间断到存在标签的处所。如下所示:
label1:
外部轮回{
内部轮回{
//…
break; //1
//…
continue; //2
//…
continue label1; //3
//…
break label1; //4
}
}
在条件1中,break间断内部轮回,并在外部轮回竣事。在条件2中,continue移回内部轮回的起始处。但在条件3中,continue label1却同时间断内部轮回以及外部轮回,并移至label1处。随后,它实际是继承轮回,但却从外部轮回开始。在条件4中,break label1也会间断所有轮回,并回到label1处,但并不从头进入轮回。也就是说,它实际是完全中止了两个轮回。
下面是for轮回的一个例子:
//: LabeledFor.java // Java’s "labeled for loop" public class LabeledFor { public static void main(String[] args) { int i = 0; outer: // Can't have statements here for(; true ;) { // infinite loop inner: // Can't have statements here for(; i < 10; i++) { prt("i = " + i); if(i == 2) { prt("continue"); continue; } if(i == 3) { prt("break"); i++; // Otherwise i never // gets incremented. break; } if(i == 7) { prt("continue outer"); i++; // Otherwise i never // gets incremented. continue outer; } if(i == 8) { prt("break outer"); break outer; } for(int k = 0; k < 5; k++) { if(k == 3) { prt("continue inner"); continue inner; } } } } // Can't break or continue // to labels here } static void prt(String s) { System.out.println(s); } } ///:~
#p#分页标题#e#
这里用到了在其他例子中已经界说的prt()要领。
留意break会间断for轮回,并且在抵达for轮回的末端之前,递增表达式不会执行。由于break跳过了递增表达式,所以递增会在i==3的环境下直接执行。在i==7的环境下,continue outer语句也会达到轮回顶部,并且也会跳过递增,所以它也是直接递增的。
下面是输出功效:
i = 0 continue inner i = 1 continue inner i = 2 continue i = 3 break i = 4 continue inner i = 5 continue inner i = 6 continue inner i = 7 continue outer i = 8 break outer
假如没有break outer语句,就没有步伐在一个内部轮回里找到出外部轮回的路径。这是由于break自己只能间断最内层的轮回(对付continue同样如此)。
虽然,若想在间断轮回的同时退出要领,简朴地用一个return即可。
下面这个例子向各人展示了带标签的break以及continue语句在while轮回中的用法:
//: LabeledWhile.java // Java's "labeled while" loop public class LabeledWhile { public static void main(String[] args) { int i = 0; outer: while(true) { prt("Outer while loop"); while(true) { i++; prt("i = " + i); if(i == 1) { prt("continue"); continue; } if(i == 3) { prt("continue outer"); continue outer; } if(i == 5) { prt("break"); break; } if(i == 7) { prt("break outer"); break outer; } } } } static void prt(String s) { System.out.println(s); } } ///:~
同样的法则亦合用于while:
(1) 简朴的一个continue会退回最内层轮回的开头(顶部),并继承执行。
(2) 带有标签的continue会达到标签的位置,并从头进入紧接在谁人标签后头的轮回。
(3) break会间断当前轮回,并移离当前标签的末端。
(4) 带标签的break会间断当前轮回,并移离由谁人标签指示的轮回的末端。
这个要领的输出功效是一目了然的:
Outer while loop i = 1 continue i = 2 i = 3 continue outer Outer while loop i = 4 i = 5 break Outer while loop i = 6 i = 7 break outer
各人要记着的重点是:在Java里独一需要用到标签的处所就是拥有嵌套轮回,并且想间断或继承多个嵌套级此外时候。
在Dijkstra的“Goto有害”论中,他最阻挡的就是标签,而非goto。跟着标签在一个措施里数量的增多,他发明发生错误的时机也越来越多。标签和goto使我们难于对措施作静态阐明。这是由于它们在措施的执行流程中引入了很多“怪圈”。但幸运的是,Java标签不会造成这方面的问题,因为它们的勾当场合已被限死,不行通过出格的方法处处通报措施的节制权。由此也引出了一个有趣的问题:通过限制语句的本领,反而能使一项语言特性越发有用。