chapter2 流程控制语句的一些新用法
首先这里对流程控制语句进行说明一下:
控制语句分为三类:
①顺序结构:代表“先执行a,再执行b”的逻辑。
②选择结构:代表“如果…,则…”的逻辑。比如switch条件语句、if语句、if-else语句、if嵌套等。
③循环结构:代表“如果…,则再继续…”的逻辑。比如while循环、do-while循环、for循环、foreach等。
这里着重讲一下switch条件语句、foreach、break和continue。
1.switch语句
基本语法形式如下:
1)switch
表示“开关”,这个开关就是 switch 关键字后面小括号里的值,小括号里要放一个整型变量或字符型变量。表达式必须为 byte,short,int,char类型,注意不可以是long类型,否则会出现错误:
点击那个红色的提示,会发现有cast into int,从而表明了小括号里不可以是long类型。
Java7 增强了 switch 语句的功能,允许 switch 语句的控制表达式是 java.lang.String 类型的变量或表达式。只能是 java.lang.String 类型,不能是 StringBuffer 或 StringBuilder 这两种字符串的类型。
2)case
case后面的类型为 char、byte、 short 或 int 的常量表达式,和switch小括号里的类型是一样的。从 Java SE 7 开始, case 标签还可以是字符串字面量。
3)default
表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。
4)break
表示“停止”,即跳出当前结构。
如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。那么就会接着执行下一个 case 分支语句。
2.foreach语句
foreach语法格式如图:
其中,“类型”为集合元素的类型,“变量名”表示集合中的每一个元素,“集合”是被遍历的集合对象或数组。
public static void main(String[] args){
// 声明并初始化int数组
int[] numbers = { 43, 32, 32, 54, 75, 7, 10 };
System.out.println("----for each----");
for (int item : numbers) {
System.out.print( item +" ");
}
}
运行结果为:
发现和for循环遍历是一样的结果。同时我们也可以知道,使用 foreach 循环遍历数组元素时无须获得数组长度,也无须根据索引来访问数组元素。
使用foreach循环时,对item进行赋值替换,发现对于原来的数组并没有任何的影响。如下面的代码:
public static void main(String[] args){
// 声明并初始化int数组
int[] numbers = { 43, 32, 32, 54, 75, 7, 10 };
System.out.println("----for each----");
for (int item : numbers) {
item = 88;
System.out.print( item +" ");
}
System.out.println();
System.out.println("----for----");
for(int i = 0; i<numbers.length; i++)
System.out.print(numbers[i] +" ");
System.out.println();
}
运行结果为:
不难看出,当使用 foreach 来迭代访问数组元素时,foreach 中的循环变量相当于一个临时变量,系统会把数组元素依次赋给这个临时变量,而这个临时变量并不是数组元素,它只是保存了数组元素的值。因此,如果希望改变数组元素的值,则不能使用这种 foreach 循环,因为在foreach循环中进行赋值,并没有对原来的数组造成任何的影响,而如果是for循环进行赋值,那么造成数组发生改变。因此如果只是单单要求遍历数组,那么通过foreach循环、for循环进行遍历都可以,foreach更优,但是如果涉及到数组的更改,那么就通过for循环来实现即可。
3.break语句与continue语句实现goto功能
在 Java 中,break 语句有 3 种作用,分别是:在 switch 语句中终止一个语句序列、使用 break 语句直接强行退出循环和使用 break 语句实现 goto 的功能。
在这里着重讲解第三个作用:break语句、continue语句实现goto功能,其语法形式为:
break label;
continue label;
通过使用扩展的 break 语句,可以终止执行一个或者几个任意代码块,这些代码块不必是一个循环或一个 switch 语句的一部分。同时这种扩展的 break 语句带有标签,跳转到标签之后,标签后面不在运行。
例如下面的代码:
public static void main(String[] args){
label:for(int i = 0; i<10; i++){//用标签(label)可以指定一个代码块,标签可以是任何合法有效的 Java 标识符,后跟一个冒号
for(int j = 0; j<8; j++){
System.out.println(j);
if(j % 2 != 0)
break label;
}
}
}
结果:
按照我们之前的理解,是跳转到标签所在的位置,继续运行,但实际的运行结果却不是这样,表明了我们之前的想法是错误的,跳转到标签所在的位置之后,并没有在运行标签后面的内容,所以输出的结果是0、1。
如果是多重嵌套,依旧如此,比如下面的代码:
public static void main(String[] args){
for(int k = 0; k<11;k++){
label:for(int i = 0; i<10; i++){//用标签(label)可以指定一个代码块,标签可以是任何合法有效的 Java 标识符,后跟一个冒号
for(int j = 0; j<8; j++){
System.out.print(j + " ");
if(j % 2 != 0)
break label;
}
}
}
}
表明了当跳转到标签所在的位置,那么第二重循环并没有在运行了,直接跳到最外部循环,也就是k,所以就运行了11次,有11个0 1这样的结果。
continue label;恰好和break label;相反,当跳转到标签之后,他会继续运行标签后面的内容。
例如:
public static void main(String[] args){
label:for(int i = 0; i<10; i++){//用标签(label)可以指定一个代码块,标签可以是任何合法有效的 Java 标识符,后跟一个冒号
for(int j = 0; j<8; j++){
System.out.print(j +" ");
if(j % 2 != 0)
continue label;
}
}
}
运行结果为:
由运行结果我们可以知道,这里有10个0 1,表明了标签后面的内容的确是继续运行的,从而证明结论是正确的,continue跳转到标签以后,标签后面的程序依然会继续运行,多重循环嵌套也是如此。
public static void main(String[] args){
for(int k = 0; k<5;k++){
label:for(int i = 0; i<10; i++){
for(int j = 0; j<8; j++){
System.out.print(j +" ");
if(j % 2 != 0)
continue label;
}
}
System.out.println();
}
}
运行结果为:
在一次证明了上面所说的结论是正确的,跳转到标签所在的位置之后,标签之后的内容仍然会继续运行。