Java核心技术卷I基础知识(原书第9版)
上QQ阅读APP看书,第一时间看更新

3.8.6 中断控制流程语句

尽管Java的设计者将goto作为保留字,但实际上并没有打算在语言中使用它。通常,使用goto语句被认为是一种拙劣的程序设计风格。当然,也有一些程序员认为反对goto的呼声似乎有些过分(例如,Donald Knuth就曾编著过一篇名为《Structured Programming with goto statements》的著名文章)。这篇文章说:无限制地使用goto语句确实是导致错误的根源,但在有些情况下,偶尔使用goto跳出循环还是有益处的。Java设计者同意这种看法,甚至在Java语言中增加了一条带标签的break,以此来支持这种程序设计风格。

下面首先看一下不带标签的break语句。与用于退出switch语句的break语句一样,它也可以用于退出循环语句。例如,

在循环开始时,如果years>100,或者在循环体中balance≥goal,则退出循环语句。当然,也可以在不使用break的情况下计算years的值,如下所示:

但是需要注意,在这个版本中,检测了两次balance<goal。为了避免重复检测,有些程序员更加偏爱使用break语句。

与C++不同,Java还提供了一种带标签的break语句,用于跳出多重嵌套的循环语句。有时候,在嵌套很深的循环语句中会发生一些不可预料的事情。此时可能更加希望跳到嵌套的所有循环语句之外。通过添加一些额外的条件判断实现各层循环的检测很不方便。

这里有一个示例说明了break语句的工作状态。请注意,标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号。

如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。对于任何使用break语句的代码都需要检测循环是正常结束,还是由break跳出。

注释:事实上,可以将标签应用到任何语句中,甚至可以应用到if语句或者块语句中,如下所示:

因此,如果希望使用一条goto语句,并将一个标签放在想要跳到的语句块之前,就可以使用break语句!当然,并不提倡使用这种方式。另外需要注意,只能跳出语句块,而不能跳入语句块。

最后,还有一个continue语句。与break语句一样,它将中断正常的控制流程。continue语句将控制转移到最内层循环的首部。例如:

如果n<0,则continue语句越过了当前循环体的剩余部分,立刻跳到循环首部。

如果将continue语句用于for循环中,就可以跳到for循环的“更新”部分。例如,下面这个循环:

如果n<0,则continue语句跳到count++语句。

还有一种带标签的continue语句,将跳到与标签匹配的循环首部。

提示:许多程序员容易混淆break和continue语句。这些语句完全是可选的,即不使用它们也可以表达同样的逻辑含义。在本书中,将不使用break和continue。