控制跳转语句(Control Jump Statement)是Java语言中与循环语句搭配使用的一种流程控制语句,控制跳转语句的使用能让循环的流程控制有更多的变化。控制跳转语句有break、continue和return三种语句。
在介绍switch语句时提到过break语句,使用它可以跳离switch语句,继续执行switch语句后的其他程序语句。不过,break语句不仅可以搭配switch语句,还可以和循环语句搭配使用。break是“中断”的意思,break语句可以中断循环的执行并跳转到标签(Label)语句定义的一段程序语句区块,类似于C++语言中的goto语句。break语句的语法如下:
标签名称: 程序语句; …… break 标签名称;
事先建立好break的标签位置及名称,当程序执行到break的程序代码时,就会根据所定义的break标签名称跳转到标签指定的地方。
【范例程序:CH03_12】
01 /*文件:CH03_12.java 02 *说明:break语句应用范例 03 */ 04 public class CH03_12{ 05 public static void main(String args[]){ 06 int i ,j; 07 System.out.println("跳离一层循环"); 08 for(i=1; i<10; i++){ 09 for(j=1; j<=i; j++){ 10 if(j==5) break ;//跳离一层循环 11 System.out.print(j); 12 } 13 System.out.println(); 14 } 15 System.out.println(); 16 17 System.out.println("跳离双层循环"); 18 out1://设置标签 19 for(i=1; i<10; i++){ 20 for(j=1; j<=i; j++){ 21 if(j==5) break out1;//跳转到标签处 22 System.out.print(j); 23 } 24 System.out.println(); 25 } 26 System.out.println(); 27 } 28 }
【程序的执行结果】
程序的执行结果可参考图3-18。
图3-18
【程序的解析】
第10行:此处的break语句只会跳离第9~12行的for循环(内层循环)。
第8~14行:执行过程如下:
i=1→j=1→显示结果:1。
i=2→j=1~2→显示结果:12。
i=3→j=1~3→显示结果:123。
……
i=5→j=1~5→显示结果:1234(不会显示5,因为已经跳离循环)。
i=6→j=1~6→显示结果:1234。
……
i=9→j=1~9→显示结果:1234。
i=10(i<10不成立,结束循环)。
第18行:设置break语句要跳转的标签位置及名称(out1):
break out1;程序语句,会跳出第19~25的双层循环。
i=1→j=1→显示结果:1。
i=2→j=1~2→显示结果:12。
i=3→j=1~3→显示结果:123。
……
i=5→j=1~5→显示结果:1234(不会显示5,而且已经跳离循环,跳转到第18行程序代码最外层循环的位置,并且结束循环)。
continue语句的功能是强制for、while、do-while等循环语句终止当前这一轮的循环,而将控制权转移到循环开始处进行下一轮循环,也就是跳过本轮循环中尚未执行的语句,开始执行下一轮的循环。continue是“继续”的意思,continue语句与break语句最大的差别在于continue只是跳过它之后未执行的语句,但并未跳离循环。continue语句也可以配合标签指令改变程序执行的流程。
【范例程序:CH03_13】
01 /*文件:CH03_13.java 02 *说明:continue语句应用范例 03 */ 04 public class CH03_13{ 05 public static void main(String args[]){ 06 int i ,j; 07 for(i=1; i<10; i++){ 08 for(j=1; j<=i; j++){ 09 if(j==5) continue ;//跳过下面的程序语句继续执行下一轮循环 10 System.out.print(j); 11 } 12 System.out.println(); 13 } 14 System.out.println(); 15 out1: 16 //设置标签 17 for(i=1; i<10; i++){ 18 for(j=1; j<=i; j++){ 19 if(j==5) continue out1;//跳转到标签处继续执行 20 System.out.print(j); 21 } 22 System.out.println(); 23 } 24 System.out.println(); 25 } 26 }
【程序的执行结果】
程序的执行结果可参考图3-19。
图3-19
【程序的解析】
第09行:当程序执行到j==5时,会跳过第10行,从第8行的循环开始执行下一轮循环。
第07~13行:执行过程如下:
i=1→j=1→显示结果:1。
i=2→j=1~2→显示结果:12。
i=3→j=1~3→显示结果:123。
……
i=5→j=1~5→显示结果:1234(不会显示5,因为continue语句会跳过第10行程序代码)。
i=6→j=1~6→显示结果:12346。
……
i=9→j=1~9→显示结果:12346789。
i=10(i<10不成立,结束循环)。
第19行:continue语句加上标签会直接跳过第20行程序语句,从第15行继续执行。
第17~23行:执行过程如下:
i=1→j=1→显示结果:1。
i=2→j=1~2→显示结果:12。
i=3→j=1~3→显示结果:123。
i=4→j=1~4→显示结果:1234。
i=5→j=1~5(不会显示5,而且跳转到第15行程序代码continue语句标签处,开始执行下一轮for循环。因为第20行的输出显示没有换行,所以输出结果彼此相连)。
因此,直到i=9→j=1~9→显示结果:12341234123412341234(从结果可以看出共有5组1234第一组是i=5的显示结果;第二组是i=6的显示结果;第三组是i=7的显示结果;第四组是i=8的显示结果;第五组是i=9的显示结果)。
return语句可以终止程序当前所在的方法(Method)回到调用方法的程序语句。在面向过程的程序设计语言中,return作为函数调用的返回语句,我们可以把面向对象程序设计语言中的方法(Method)理解成函数(Function)。使用return语句时,可以将方法中的变量值或表达式运算的结果值返回给调用的程序语句,不过返回值的数据类型要和声明的数据类型相符合,如果方法不需要返回值,那么可以将方法声明为void数据类型。以下是return语句的使用方法。
【return语句的语法】
return 变量或表达式; return; // 没有返回值
【范例程序:CH03_14】
01 /*文件:CH03_14.java 02 *说明:return语句应用范例 03 */ 04 public class CH03_14{ 05 public static void main(String args[]){ 06 int ans; 07 ans=sum(10);//调用sum方法 08 System.out.println("1~10的累加"); 09 System.out.println("ans="+ans); 10 } 11 12 //sum方法 13 static int sum(int n){ 14 int sum=0; 15 for(int i=1; i<=n; i++){ 16 sum+=i; 17 } 18 return sum; //返回sum变量的值 19 } 20 }
【程序的执行结果】
程序的执行结果可参考图3-20。
图3-20
【程序的解析】
第07行:用变量ans来接收sum方法返回的值,其中10为传递的实际参数。
第13~19行:sum()方法的定义区块,将该方法声明为static,可以直接被调用和执行,而不必通过类对象的方式。
for-each循环和传统for循环不同的地方是,for-each可以直接读取“集合(Set)类型”的数据,如数组。for-each可以使循环自动化,不用编程人员动手设置循环的计数值、起始值和循环条件(或循环终止值),也不用设置“数组的索引值”,好处是避免索引值超过数组边界而造成错误。for-each语句的语法如下:
for(变量名称:集合类型){ 程序语句区块; }
下面举个例子来说明。假如A是一个数组,其元素的内容或值是整数类型的。如果要读取数组中元素的值,一般的方式是使用传统for循环来执行读取的操作,而读取数组元素是通过“索引值”(也称为数组的“下标值”),但是这种方式的风险是可能会引发索引值超过数组边界的错误。
for-each改变了传统的做法,当进入for-each循环时,读取方式不再是通过索引值,而是直接读取数组中的元素值,因此第一次进入循环,x=1,这个1不是指数组的索引值,而是指元素值。所以x是否声明成整数类型(int)要由数组来决定。图3-21中的两个图对比了传统for循环与for-each循环读取上的不同之处。
图3-21
对比语法,“int x”就是“变量名称”部分,“A”就是“集合类型”部分,集合类型指的是所声明的数组。
【范例程序:CH03_15】
01 /*文件:CH03_15.java 02 *说明:for-each循环应用范例 03 */ 04 05 public class CH03_15{ 06 public static void main(String[] ages){ 07 int A[]={1,2,3,4,5,6,7,8,9}; 08 char B[]={'H','a','p','p','y'}; 09 System.out.println("数字数组"); // 用传统for循环读取数组元素 10 for (int i=0;i<A.length;i++){ 11 System.out.print(A[i]+" "); 12 } 13 System.out.println('\n'); 14 System.out.println("字符数组"); 15 for (int i=0;i<B.length;i++) { 16 System.out.print(B[i]+" "); 17 } 18 System.out.println('\n'); 19 System.out.println("数字数组"); // 用for-each循环读取数组元素 20 for (int i:A){ 21 System.out.print(i+" "); //直接读取数组中的元素值 22 } 23 System.out.println('\n'); 24 System.out.println("字符数组"); 25 for (char i:B){ 26 System.out.print(i+" ");// 因为数组B的元素值是字符, 所以i必须声明成char 数据类型 27 } 28 System.out.println('\n'); 29 } 30 }
【程序的执行结果】
程序的执行结果可参考图3-22。
图3-22
【程序的解析】
第20行:for-each循环读取数组中的元素值,在for-each声明中的“变量”的数据类型是由数组的元素决定的。“变量”的属性是“只读的”,意思就是只能读取的属性,不能更改或写入的属性。
如果是多维数组,那么将如何使用for-each循环呢?下面通过范例程序来实现多维数组的for-each循环的用法。
【范例程序:CH03_16】
01 /*文件:CH03_16.java 02 *说明:for-each——读取多维数组的应用范例 03 */ 04 05 public class CH03_16{ 06 public static void main(String[] ages){ 07 int A[][]=new int[2][3]; //声明多维数组 08 for (int i=0;i<2;i++){ //给数组中的元素赋值,并且读取数组元素值 09 for (int j=0;j<3;j++){ 10 A[i][j]=i+j; 11 System.out.print(A[i][j]+" "); 12 } 13 } 14 System.out.println('\n'); 15 for (int i[]:A){ // 改用for-each循环读取数组元素值 16 for (int j:i){ 17 System.out.print(j+" "); 18 } 19 } 20 System.out.println('\n'); 21 } 22 }
【程序的执行结果】
程序的执行结果可参考图3-23。
图3-23
【程序的解析】
第15~19行:二维数组其实就是数组中的数组。因此,在第15行的外层循环,int i[]表示读取的是一整组的一维数组,在第16行的内层循环则是针对外层循环所指定的一维数组读取其中的元素值。