2.4 控制流程语句
控制流程语句用于控制程序按照一定流程来执行。
2.4.1 if-then
if-then语句是指只有if后面是true时才执行特定的代码。

如果if后面是false,就跳到if-then语句后面。语句可以省略中括号,例如:

注意
语句可以省略中括号,但在编码规范里面不推荐使用,因为极易让人看错。
2.4.2 if-then-else
if-then-else语句在if后面是false时提供了第二个执行路径。

下面是一个完整的例子:

输出为:
Grade = C
2.4.3 switch
switch语句可以有许多可能的执行路径,可以使用byte、short、char和int基本数据类型,也可以是枚举类型、String以及少量的原始类型的包装类Character、Byte、Short和Integer。
下面是一个SwitchDemo例子:


其中,break语句是为了终止switch语句。
以下是一个不使用switch语句的例子:


输出为:
August September October November December
从技术上来说,最后一个break并不是必需的,因为流程跳出switch语句,但是仍然推荐使用break,主要是防止在修改代码后造成遗漏而出错。default用于处理所有不明确值的情况。
下面的例子展示了多个case对应一个结果的情况:

输出为:
Number of Days = 29
从Java 7开始,可以在switch语句里面使用String,下面给出一个例子:



输出为:
8
注意
switch语句表达式中不能有null。
2.4.4 while
while语句在判断条件是true时执行语句块,语法如下:

while语句计算的表达式必须返回boolean值。如果表达式计算为true,while语句执行while块的所有语句。while语句继续测试表达式,然后执行它的块,直到表达式计算为false。
以下是一个完整的例子:

输出为:
Count is: 1 Count is: 2 Count is: 3 Count is: 4 Count is: 5 Count is: 6 Count is: 7 Count is: 8 Count is: 9 Count is: 10
用while语句可以实现一个无限循环,示例如下:

2.4.5 do-while
do-while语句的语法如下:
do { statement(s) } while (expression);
do-while语句和while语句的区别是,do-while计算表达式时在循环的底部,而不是顶部,do块的语句至少会执行一次。
以下是一个示例:

输出为:
Count is: 1 Count is: 2 Count is: 3 Count is: 4 Count is: 5 Count is: 6 Count is: 7 Count is: 8 Count is: 9 Count is: 10
2.4.6 for
for语句提供一种紧凑的方式来遍历一个范围值,该语句也被称为“for循环”,因为它反复循环,直到满足特定的条件。for语句的通常形式表述如下:
for (initialization; termination; increment) { statement(s) }
使用for语句时要注意:
· initialization初始化循环,执行一次,作为循环的开始。
· 当termination计算为false时,循环结束。
· increment会在循环中迭代执行。该表达式可以接受递增或者递减的值。
以下是一个示例:

输出为:
Count is: 1 Count is: 2 Count is: 3 Count is: 4 Count is: 5 Count is: 6 Count is: 7 Count is: 8 Count is: 9 Count is: 10
注意,代码是在initialization中声明变量的。该变量的存活范围从它的声明到for语句块的结束为止。所以,它可以用在termination和increment中。如果控制for语句的变量不需要在循环外部使用,那么最好是在initialization中声明。变量命名为i、j、k是经常用来控制for循环的。在initialization中声明它们,可以限制它们的生命周期,减少错误。
for循环的3个表达式都是可选的,如果想表达无限循环,可以这么写:

for语句还可以用来迭代集合和数组,这个形式有时被称为增强的for语句,可以用来让你的循环更加紧凑,易于阅读。为了说明这一点,考虑下面的数组:
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
使用增强的for语句来循环数组:

输出:
Count is: 1 Count is: 2 Count is: 3 Count is: 4 Count is: 5 Count is: 6 Count is: 7 Count is: 8 Count is: 9 Count is: 10
尽可能使用这种形式的for替代传统的for形式。
2.4.7 break
break语句有两种形式:标签和非标签。在前面的switch语句中,看到的break语句就是非标签形式。可以使用非标签break结束for、while、do-while循环,例如:

这个程序在数组中查找数字12。当找到值时,break语句会结束for循环,控制流跳转到for循环后面的语句。程序输出是:
Found 12 at index 4
无标签break语句结束最里面的switch、for、while、do-while语句,而标签break结束最外面的语句。接下来的程序(BreakWithLabelDemo)类似前面的程序,但使用嵌套循环在二维数组里寻找一个值。值找到后,标签break语句结束最外面的for循环:

程序输出是:
Found 12 at 1, 0
break语句结束标签语句,不传送控制流到标签处。控制流传送紧随标记声明。
注意
Java没有类似于C语言的goto语句,带标签的break语句实现了类似的效果。
2.4.8 continue
continue语句忽略for、while、do-while的当前迭代。非标签模式忽略最里面的循环体,然后计算循环控制的boolean表达式。接下来的程序(ContinueDemo)通过一个字符串计算字母“p”出现的次数:如果当前字符不是p,continue语句跳过循环的其他代码,然后处理下一个字符;如果当前字符是p,程序自增字符数。

程序输出:
Found 9 p's in the string
为了更清晰地看出效果,尝试去掉continue语句,重新编译。再跑程序,count将是错误的,输出是35,而不是9。
带标签的continue语句忽略标签标记外层循环的当前迭代。下面的程序例子(ContinueWithLabelDemo)使用嵌套循环在字符串的子串中搜索子串。需要两个嵌套循环:一个迭代子串,一个迭代正在被搜索的子串。下面的程序ContinueWithLabelDemo使用continue的标签形式忽略最外层的循环。

这里是程序输出:
Found it
2.4.9 return
最后的分支语句是return语句。return语句从当前方法退出,控制流返回到方法调用处。return语句有两种形式:一个返回值,一个不返回值。为了返回一个值,简单在return关键字后面把值放进去(或者放一个表达式计算):

return值的数据类型必须和方法声明的返回值类型符合。当方法声明为void时,使用如下形式的return不需要返回值:
