控制流程
Java的控制流程用于使程序按正确的顺序逐步进行,为程序提供了运行方向。分为选择类控制流程和循环类控制流程。
选择类控制流程
if-else流程
if-else流程是最基本的选择类控制流程。格式为:if (expr) statement1; [else statement2;]。expr是逻辑表达式,如果为true,则执行statement1;如果为false则不执行,如果有else子句,则执行statement2。
默认情况下else子句会与最近的if子句配对,可以使用“{ }”来表示else子句与哪一个if子句匹配。例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @Test 2 void testIfelse() { 3 int a = 6, b = 7; 4 if (a < 0) 5 if (a < b) 6 a = b; 7 else // 与if (a < b)配对 8 b = a; 9 System.out.println("a = " + a); 10 System.out.println("b = " + b); 11 System.out.println(); 12 a = 6; 13 b = 7; 14 if (a < 0) { 15 if (a < b) 16 a = b; 17 } 18 else // 与if (a < 0)配对 19 b = a; 20 System.out.println("a = " + a); 21 System.out.println("b = " + b); 22 }
输出结果:
很明显,第一个if-else流程的else子句与if (a < b)配对;为了使else子句与if (a < 0)配对,需要加入“{ }”。
if-else流程有两种嵌套:
1.if (expr1) statement1; else if (expr2) statement2; else statement3;
2.if (expr1) { if (expr2) statement1; else statement2;} else statement3;
switch流程
switch流程适用于多种选择的情况。格式为:switch (expr) { case val1 : statement1; case val2 : statement2; ... [default : statement3;]}
switch根据表达式expr的值选择对应的case块,如果没有一个case块与之匹配且有default块,则进入default块。
switch中case块或default块需要用break语句来退出程序,如果该程序块是switch的最后一个块则不用break语句。
default块可以放在任何位置,并不一定是在最后,但通常情况下default块都放在最后。
欲使得多个case块执行同一段程序,则只需声明前面几个case块,再最后一个case块写入程序。
switch有一个特点:在一个case块中声明的变量只能在该case块中使用,但是在其他case块不能声明同名变量。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @Test 2 void testSwitch() { 3 String s = "Mon"; 4 String str; 5 switch (s) { 6 case "Mon" : 7 str = "Monday"; 8 break; 9 case "Tue" : 10 str = "Tuesday"; 11 break; 12 case "Wed" : 13 str = "Wednesday"; 14 break; 15 case "Thu" : 16 str = "Thursday"; 17 break; 18 case "Fri" : 19 str = "Friday"; 20 break; 21 case "Sat" : 22 str = "Saturday"; 23 break; 24 case "Sun" : 25 str = "Sunday"; 26 break; 27 default : 28 str = "No Result"; 29 } 30 System.out.println(str); 31 }
输出结果:
JDK12版本新增了一种switch表达式,使得switch语句的格式变得更加美观。格式为:switch (expr) { case val1 -> {statement1;} case val2 -> {statement2;} ... [default -> {statementN;}]}
switch表达式会根据expr的值执行对应的case块后面“{ }”括起来的语句,没有与之匹配的case块,若存在default块,则执行default块。
由于用“{ }”括起了每一块的语句,无需再使用break语句来退出程序。如果只有一个语句可不加“{ }”。
switch表达式允许一个case块有多个值,只需要用“,”将各个值分开即可。表示当expr为这些值的其中之一时执行该case块。
上面的程序使用switch表达式可以改为:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @SuppressWarnings("preview") 2 @Test 3 void testSwitch() { 4 String s = "Mon"; 5 String str; 6 switch (s) { 7 case "Mon" -> str = "Monday"; 8 case "Tue" -> str = "Tuesday"; 9 case "Wed" -> str = "Wednesday"; 10 case "Thu" -> str = "Thursday"; 11 case "Fri" -> str = "Friday"; 12 case "Sat" -> str = "Saturday"; 13 case "Sun" -> str = "Sunday"; 14 default -> str = "No Result"; 15 } 16 System.out.println(str); 17 }
输出结果:
switch表达式可以直接返回值。格式为:type value = switch (expr) { case val1 -> value1; case val2 -> value2; ... default -> valueN;};
上面的程序可以再改的更加美观:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @SuppressWarnings("preview") 2 @Test 3 void testSwitch() { 4 String s = "Mon"; 5 String str = switch (s) { 6 case "Mon" -> "Monday"; 7 case "Tue" -> "Tuesday"; 8 case "Wed" -> "Wednesday"; 9 case "Thu" -> "Thursday"; 10 case "Fri" -> "Friday"; 11 case "Sat" -> "Saturday"; 12 case "Sun" -> "Sunday"; 13 default -> "No Result"; 14 }; 15 System.out.println(str); 16 }
输出结果:
循环类控制流程
循环类控制流程的作用是,由循环初始、循环迭代、循环结束三部分控制,重复执行循环体。
for流程
for流程的格式为:for (初始; 结束; 迭代) { 循环体 }
初始部分和迭代部分可以用“,”隔开多个部分,而结束部分是一个逻辑表达式,用于判断结束循环的时机。
可以在初始部分中声明变量,该变量只能在当前for流程中使用。
foreach流程
foreach流程是一种增强的for流程,适用于数组或Collection类对象的遍历。格式为:for (type item : items) { 循环体 }
items是数组或Collection类对象,而item代表items的元素,所以item的类型type为items中的元素类型。
while流程
while流程的格式为:初始; while (结束) { 循环体; 迭代;}
进入while流程时会先进行一次结束判断,为true才进入循环。
do-while流程
do-while流程的格式为:初始; do { 循环体; 迭代;} while (结束);
进入do-while流程时会先进行一次循环,再进行结束判断。
区别
for流程和while流程都是先判断后执行,而do-while流程是先执行后判断。例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @Test 2 void testCirculation() { 3 int i; 4 // for 5 for (i = 0; i < 0; i++) ; 6 System.out.println("for流程:" + i); 7 // while 8 i = 0; 9 while (i < 0) { 10 i++; 11 } 12 System.out.println("while流程:" + i); 13 // do-while流程 14 i = 0; 15 do { 16 i++; 17 } while (i < 0); 18 System.out.println("do-while流程:" + i); 19 }
输出结果:
for流程和while流程都是先判断,由于i<0为false,不进入循环,未执行i++语句,所以输出的i的值都是初始值0。而do-while流程是先执行,所以会执行一次i++语句,所以输出的i的值是1。
退出流程
可以使用break和continue语句来退出流程。
break语句是退出整个循环流程;continue语句是退出当前循环,进入下一次循环。
Java允许在循环程序块前使用标号标识,然后在break语句或continue语句后使用该标号,表示退出该循环。该方法一般在需要退出多层循环时使用。例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 @Test 2 void testLabel() { 3 int i = 0, j = 0; 4 for (i = 0; i < 3; i++) 5 for (j = 0; j < 5; j++) { 6 if (j == 2) break; 7 } 8 System.out.println("i = " + i); 9 System.out.println("j = " + j); 10 System.out.println(); 11 outer : for (i = 0; i < 3; i++) 12 for (j = 0; j < 5; j++) { 13 if (j == 2) break outer; 14 } 15 System.out.println("i = " + i); 16 System.out.println("j = " + j); 17 }
输出结果:
第一段for流程中的break语句退出的是内层的for流程,所以外层的for流程会继续执行,直到i=3为止。而第二段for流程中的break语句退出的是标有outer标号的for流程,即外层的for流程,所以i=0。