4.控制执行流程
java使用了c所有的控制流程语句,涉及到的关键字有:if-else、while、do-while、for、return、break以及选择语句break.java并不支持goto语句。
4.1true和false
条件语句都利用条件表达式的真或假来决定执行路径。前面介绍的关系操作符都可以用来构造条件表达式。
4.2if-else
if-else是最基本的控制程序流程的形式,其中else是可选的,相关的形式有:
if(boolean-exp){
statement;
}
或者
if(boolean-exp){
statement;
}else{
statement;
}
亦或者
if(boolean-exp){
statement;
}else if(boolean-exp){
statement;
}else if(boolean-exp){
statement;
}......
4.3迭代
while、do-while、for用来控制循环,语句会重复执行,直到控制作用的布尔表达式得到假的结果位置。
while的循环表达式格式:
while(boolean-exp){
statement;
}
循环刚开始时会计算一次布尔表达式;在语句的下一次迭代开始前再计算一次。
4.3.1do-while
do-while的格式:
do{
statement;
}while(boolean-exp);
与while循环语句的差别是多执行一次。
4.3.2 for
for循环可能是最长用到的迭代形式,这种迭代在第一次要进行初始化,随后进行条件测试,在每次迭代结束前进行某种形式的步进,其格式为:
for(initialization;boolean-exp;step){
statement;
}
具体实例如下,求1到10的整数和
int res = 0;
for(int i = 1;i<=10;i++){
res+=i;
}
System.out.println(res);
其中i的作用范围仅在for循环的范围内,
4.3.3逗号操作符
java中唯一用到逗号操作符的地方是for循环的控制表达式。在控制表达式的初始化和步进控制部分,可以使用一系列的逗号分隔语句。
for(int i = 1,j=i+10;i<5;i++,j=i*2){
System.out.pringln(j);
}
定义多个变量的这种能力只限于for循环使用。
4.4 foreach语法
Java SE5引入了更简洁的for语法用于数组和容器。不必创建int变量去对由访问项构成的序列进行计数,foreach自动产生每一项。
例如遍历一个float数组
public class ForEachFolat{
public static void main(String[]args){
Random rand = new Random(47);
float[]f=new float[10];
for(int i=0;i<10;i++){
f[i] = rand.nextFloat();
}
for(float x:f){
System.out.println(x);
}
}
}
即定义了一个float类型的变量x,将数组f的每一个元素值赋予x,对x进行操作。
从上述例句可以看到foreach的格式为:
for(datatype tempName:Name){
statement;
}
使用foreach,要事先存在该数组或对象才可以。foreach使得录入代码变得更简洁,阅读更容易。
4.5 return
return关键字有两个方面的用途:一方面指定一个方法返回什么值,另一方法它会导致当前方法的退出,并返回那个值。
如果在void的方法中没有一个return语句,该方法的结尾处会有一个隐式的return,因此在方法中并非一定要有一个return语句。如果一个方法不是void,则一定要存在return语句,确保方法有返回。
4.6 break和continue
在任何迭代语句的主体部分都可以使用break和continue,其中使用break强行退出循环,不执行循环中的剩余语句,而continue则是停止执行当前的迭代,退回到循环起始处,开始下一次迭代。
//: control/BreakAndContinue.java
// Demonstrates break and continue keywords.
import static net.mindview.util.Range.*;
public class BreakAndContinue {
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
if(i == 74) break; // Out of for loop
if(i % 9 != 0) continue; // Next iteration
System.out.print(i + " ");
}
System.out.println();
// Using foreach:
for(int i : range(100)) {
if(i == 74) break; // Out of for loop
if(i % 9 != 0) continue; // Next iteration
System.out.print(i + " ");
}
System.out.println();
int i = 0;
// An "infinite loop":
while(true) {
i++;
int j = i * 27;
if(j == 1269) break; // Out of loop
if(i % 10 != 0) continue; // Top of loop
System.out.print(i + " ");
}
}
} /* Output:
0 9 18 27 36 45 54 63 72
0 9 18 27 36 45 54 63 72
10 20 30 40
*///:~
4.7 goto
goto起源于汇编语言的程序控制:“条件A成立,则跳到这里,否则跳到那里”。goto语句是在源码级上跳转,若一个程序总是从一个地方跳到另一个地方,有什么办法能够识别程序的控制流程。
goto是java的一个保留字,在语言中并未使用它;java没有使用goto,但是也可以完成goto的功能,使用了标签的机制。
标签是后面带有冒号的标识符,例如:
label1:
利用break或continue与标签配合,可以中断循环,直到标签的所在位置。
例如:
label1:
outer-iteration{
inner-iteration{
//....
break;//(1)
//.....
continue;//(2)
//....
continue label1;//(3)
//....
break label1;//(4)
}
}
在(1)中break中断内部迭代,回到外部迭代。在(2)中,continue使执行点移到内部迭代的起始点。在(3)处,continue label1同时中断内部迭代和外部迭代,直接转到label1处;随后它继续迭代,不过是从外部迭代开始,相当于等价一个break;在(4),break label1中断了所有迭代,并回到了label1,但不重新进入迭代,即完全中断了两个迭代。
//: control/LabeledFor.java
// For loops with "labeled break" and "labeled continue."
import static net.mindview.util.Print.*;
public class LabeledFor {
public static void main(String[] args) {
int i = 0;
outer: // Can't have statements here
for(; true ;) { // infinite loop
inner: // Can't have statements here
for(; i < 10; i++) {
print("i = " + i);
if(i == 2) {
print("continue");
continue;
}
if(i == 3) {
print("break");
i++; // Otherwise i never
// gets incremented.
break;
}
if(i == 7) {
print("continue outer");
i++; // Otherwise i never
// gets incremented.
continue outer;
}
if(i == 8) {
print("break outer");
break outer;
}
for(int k = 0; k < 5; k++) {
if(k == 3) {
print("continue inner");
continue inner;
}
}
}
}
// Can't break or continue to labels here
}
} /* Output:
i = 0
continue inner
i = 1
continue inner
i = 2
continue
i = 3
break
i = 4
continue inner
i = 5
continue inner
i = 6
continue inner
i = 7
continue outer
i = 8
break outer
*///:~
如果想在中断循环的同时退出方法,可以使用一个return语句即可。
这些规则同样适用于while。
4.8 switch
switch被归划为一种选择语句,根据整数表达式,switch从一系列代码中选出一段去执行。格式为:
switch(变量){
case 常量1:
语句;
break;
case 常量2:
语句;
break;
...
default:
语句;
break;
}
每个case都以一个break结尾,可以使执行流程跳转到switch主体末尾,这个是可选的,如果省略了break,则继续执行下面的case语句。如果case中没有相符合的语句,则执行default语句。
switch(表达式)中的返回值必须是:byte,short,char,int,枚举,String,没有long类型;case子句中的值必须是常量,且所有case值应该是不同的。
下面例子是随机生成字母,判断是元音字母还是辅音字母。
//: control/VowelsAndConsonants.java
// Demonstrates the switch statement.
import java.util.*;
import static net.mindview.util.Print.*;
public class VowelsAndConsonants {
public static void main(String[] args) {
Random rand = new Random(47);
for(int i = 0; i < 100; i++) {
int c = rand.nextInt(26) + 'a';
printnb((char)c + ", " + c + ": ");
switch(c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u': print("vowel");
break;
case 'y':
case 'w': print("Sometimes a vowel");
break;
default: print("consonant");
}
}
}
} /* Output:
y, 121: Sometimes a vowel
n, 110: consonant
z, 122: consonant
b, 98: consonant
r, 114: consonant
n, 110: consonant
y, 121: Sometimes a vowel
g, 103: consonant
c, 99: consonant
f, 102: consonant
o, 111: vowel
w, 119: Sometimes a vowel
z, 122: consonant
...
*///:~
switch语句的执行效率比if稍微高一些,具体数值不多的时候建议使用switch语句,对区间的判断使用if语句更方便。