控制流语句
if-then 语句
if-then
语句是最基本的控制流语句之一。它告诉你的程序仅当特定测试评估为 true
时才执行代码的特定部分。例如,Bicycle
类可以仅当自行车已在运动时才允许制动器降低自行车的速度。applyBrakes()
方法的一种可能的实现如下所示
void applyBrakes() {
// the "if" clause: bicycle must be moving
if (isMoving){
// the "then" clause: decrease current speed
currentSpeed--;
}
}
如果此测试评估为 false
(表示自行车未在运动),则控制将跳转到 if-then
语句的末尾。
此外,如果“then”子句仅包含一个语句,则可以省略开括号和闭括号
void applyBrakes() {
// same as above, but without braces
if (isMoving)
currentSpeed--;
}
决定何时省略括号是个人喜好问题。省略它们可能会使代码更脆弱。如果稍后将第二个语句添加到“then”子句中,一个常见的错误是忘记添加新需要的括号。编译器无法捕获这种错误;你只会得到错误的结果。
if-then-else 语句
if-then-else
语句在“if”子句评估为 false
时提供第二条执行路径。你可以在 applyBrakes()
方法中使用 if-then-else
语句,以便在自行车未在运动时应用制动器时采取一些措施。在这种情况下,该操作只是打印一条错误消息,指出自行车已经停止。
void applyBrakes() {
if (isMoving) {
currentSpeed--;
} else {
System.err.println("The bicycle has already stopped!");
}
}
以下程序 IfElseDemo
根据测试分数的值分配等级:90% 或更高的分数为 A,80% 或更高的分数为 B,依此类推。
class IfElseDemo {
public static void main(String[] args) {
int testscore = 76;
char grade;
if (testscore >= 90) {
grade = 'A';
} else if (testscore >= 80) {
grade = 'B';
} else if (testscore >= 70) {
grade = 'C';
} else if (testscore >= 60) {
grade = 'D';
} else {
grade = 'F';
}
System.out.println("Grade = " + grade);
}
}
程序的输出为
Grade = C
你可能已经注意到,testscore
的值可以满足复合语句中的多个表达式:76 >= 70
和 76 >= 60
。但是,一旦满足条件,就会执行相应的语句(grade = 'C';
),并且不会评估其余条件。
while 和 do-while 语句
while
语句在特定条件为 true
时不断执行语句块。它的语法可以表示为
while (expression) {
statement(s)
}
while
语句评估表达式,该表达式必须返回 boolean
值。如果表达式评估为 true
,则 while
语句执行 while
块中的 statement(s)
。while
语句继续测试表达式并执行其块,直到表达式评估为 false
为止。使用 while
语句打印从 1 到 10 的值可以像以下 WhileDemo
程序中那样完成
class WhileDemo {
public static void main(String[] args){
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}
}
你可以使用 while
语句实现无限循环,如下所示
while (true){
// your code goes here
}
Java 编程语言还提供 do-while
语句,它可以表示为
do {
statement(s)
} while (expression);
do-while
和 while
之间的区别在于,do-while
在循环底部而不是顶部评估其表达式。因此,do
块中的语句始终至少执行一次,如以下 DoWhileDemo
程序所示
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 11);
}
}
for 语句
for
语句提供了一种紧凑的方式来迭代一系列值。程序员通常将其称为“for 循环”,因为它是以重复循环直到满足特定条件的方式来实现的。for
语句的一般形式可以表示为
for (initialization; termination; increment) {
statement(s)
}
使用此版本的 for 语句时,请记住
- 初始化表达式初始化循环;它在循环开始时执行一次。
- 当终止表达式评估为
false
时,循环终止。 - 增量表达式在每次循环迭代后调用;此表达式可以增量或减量值,这完全可以接受。
以下程序 ForDemo
使用 for
语句的一般形式将数字 1 到 10 打印到标准输出
class ForDemo {
public static void main(String[] args){
for(int i = 1; i < 11; i++){
System.out.println("Count is: " + i);
}
}
}
此程序的输出为
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
请注意代码如何在初始化表达式中声明一个变量。此变量的作用域从其声明扩展到 for
语句控制的块的末尾,因此它也可以在终止和增量表达式中使用。如果控制 for
语句的变量在循环外部不需要,最好在初始化表达式中声明该变量。名称 i
、j
和 k
通常用于控制 for
循环;在初始化表达式中声明它们会限制它们的生命周期并减少错误。
for
循环的三个表达式是可选的;可以创建无限循环,如下所示
// infinite loop
for ( ; ; ) {
// your code goes here
}
for
语句还有另一种形式,专为迭代集合和数组而设计。这种形式有时称为增强 for 语句,可用于使你的循环更紧凑且易于阅读。为了演示,请考虑以下数组,它包含数字 1 到 10
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
以下程序 EnhancedForDemo
使用增强 for 循环遍历数组
class EnhancedForDemo {
public static void main(String[] args){
int[] numbers =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int item : numbers) {
System.out.println("Count is: " + item);
}
}
}
在此示例中,变量 item
保存来自 numbers 数组的当前值。此程序的输出与之前相同
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
我们建议尽可能使用这种形式的 for
语句,而不是使用一般形式。
break 语句
break
语句有两种形式:带标签和不带标签。你在之前关于 switch
语句的讨论中看到了不带标签的形式。你还可以使用不带标签的 break
来终止 for
、while
或 do-while
循环,如以下 BreakDemo
程序所示
class BreakDemo {
public static void main(String[] args) {
int[] arrayOfInts =
{ 32, 87, 3, 589,
12, 1076, 2000,
8, 622, 127 };
int searchfor = 12;
int i;
boolean foundIt = false;
for (i = 0; i < arrayOfInts.length; i++) {
if (arrayOfInts[i] == searchfor) {
foundIt = true;
break;
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at index " + i);
} else {
System.out.println(searchfor + " not in the array");
}
}
}
此程序在数组中搜索数字 12。break
语句在找到该值时终止 for
循环。然后控制流将转移到 for
循环之后的语句。此程序的输出为
Found 12 at index 4
不带标签的 break
语句终止最内层的 switch
、for
、while
或 do-while
语句,但带标签的 break
语句终止外部语句。以下程序 BreakWithLabelDemo
与之前的程序类似,但使用嵌套的 for
循环在二维数组中搜索值。找到该值后,带标签的 break
会终止外部 for
循环(标记为“search”)
class BreakWithLabelDemo {
public static void main(String[] args) {
int[][] arrayOfInts = {
{ 32, 87, 3, 589 },
{ 12, 1076, 2000, 8 },
{ 622, 127, 77, 955 }
};
int searchfor = 12;
int i;
int j = 0;
boolean foundIt = false;
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length;
j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at " + i + ", " + j);
} else {
System.out.println(searchfor + " not in the array");
}
}
}
这是程序的输出。
Found 12 at 1, 0
break
语句终止带标签的语句;它不会将控制流转移到标签。控制流将转移到带标签(终止)语句之后的语句。
continue 语句
continue
语句跳过 for
、while
或 do-while
循环的当前迭代。不带标签的形式跳过最内层循环主体末尾,并评估控制循环的布尔表达式。以下程序 ContinueDemo
遍历 String
,计算字母 p
的出现次数。如果当前字符不是 p
,则 continue
语句跳过循环的其余部分并继续下一个字符。如果是 p
,则程序会增加字母计数。
class ContinueDemo {
public static void main(String[] args) {
String searchMe = "peter piper picked a " + "peck of pickled peppers";
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
// interested only in p's
if (searchMe.charAt(i) != 'p')
continue;
// process p's
numPs++;
}
System.out.println("Found " + numPs + " p's in the string.");
}
}
以下是此程序的输出
Found 9 p's in the string.
为了更清楚地看到这种效果,请尝试删除 continue
语句并重新编译。当你再次运行程序时,计数将不正确,显示它找到了 35 个 p
,而不是 9 个。
带标签的 continue
语句跳过用给定标签标记的外部循环的当前迭代。以下示例程序 ContinueWithLabelDemo
使用嵌套循环在另一个字符串中搜索子字符串。需要两个嵌套循环:一个用于迭代子字符串,另一个用于迭代要搜索的字符串。以下程序 ContinueWithLabelDemo
使用 continue
的带标签的 test
来跳过外部循环中的迭代。
class ContinueWithLabelDemo {
public static void main(String[] args) {
String searchMe = "Look for a substring in me";
String substring = "sub";
boolean foundIt = false;
int max = searchMe.length() -
substring.length();
test:
for (int i = 0; i <= max; i++) {
int n = substring.length();
int j = i;
int k = 0;
while (n-- != 0) {
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
foundIt = true;
break test;
}
System.out.println(foundIt ? "Found it" : "Didn't find it");
}
}
以下是此程序的输出。
Found it
return 语句
下一个分支语句是 return
语句。return
语句退出当前方法,控制流返回到调用该方法的位置。return
语句有两种形式:一种返回一个值,另一种不返回。要返回一个值,只需在 return
关键字之后加上该值(或计算该值的表达式)。
return ++count;
返回的值的数据类型必须与方法声明的 return
值的类型匹配。当方法声明为 void
时,请使用不返回值的 return
形式。
return;
类和对象部分将涵盖编写方法所需的一切知识。
yield 语句
最后一个分支语句是 yield
语句。yield
语句退出它所在的当前 switch
表达式。yield
语句后面始终是一个表达式,该表达式必须产生一个值。此表达式不能是 void
。此表达式的值是封闭 switch
表达式产生的值。
以下是一个 yield
语句的示例。
class Test {
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public int calculate(Day d) {
return switch (d) {
case SATURDAY, SUNDAY -> 0;
default -> {
int remainingWorkDays = 5 - d.ordinal();
yield remainingWorkDays;
}
};
}
}
最后更新: 2021 年 9 月 22 日