Java的控制流程用于使程序按正确的顺序逐步进行,为程序提供了运行方向。分为选择类控制流程和循环类控制流程。
选择类控制流程
if-else流程
if-else流程是最基本的选择类控制流程。格式为:if (expr) statement1; [else statement2;]。expr是逻辑表达式,如果为true,则执行statement1;如果为false则不执行,如果有else子句,则执行statement2。
默认情况下else子句会与最近的if子句配对,可以使用“{ }”来表示else子句与哪一个if子句匹配。例如:
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块不能声明同名变量。
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表达式可以改为:
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;};
上面的程序可以再改的更加美观:
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流程是先执行后判断。例如:
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语句后使用该标号,表示退出该循环。该方法一般在需要退出多层循环时使用。例如:
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。