ZetCode

Java 流程控制

最后修改于 2024 年 2 月 22 日

在本文中,我们将介绍 Java 中的程序流程控制。我们将使用几个关键字来控制 Java 程序的流程。

控制流语句

在 Java 语言中,有几个关键字用于改变程序的流程。语句可以多次执行,也可以仅在特定条件下执行。ifelseswitch 语句用于测试条件,whilefor 语句用于创建循环,breakcontinue 语句用于改变循环。

当程序运行时,语句从源文件的顶部到底部逐行执行。

if 语句

if 语句具有以下一般形式

if (expression) {

    statement;
}

if 关键字用于检查表达式是否为真。如果为真,则执行语句。该语句可以是单个语句或复合语句。复合语句由大括号括起来的多个语句组成。如果主体中只有一个语句,则大括号是可选的。

Main.java
import java.util.Random;

void main() {

    var r = new Random();
    int num = r.nextInt();

    if (num > 0) {

        System.out.println("The number is positive");
    }
}

生成一个随机数。如果该数字大于零,我们向终端打印一条消息。

var r = new Random();
int num = r.nextInt();

这两行代码生成一个随机整数。该数字可以是正数或负数。

if (num > 0) {

    System.out.println("The number is positive");
}

使用 if 关键字,我们检查生成的数字是否大于零。if 关键字后跟一对圆括号。在括号内,我们放置一个表达式。该表达式的结果是一个布尔值。如果布尔值为真,则执行由两个大括号括起来的代码块。在我们的例子中,字符串 "The number is positive" 将被打印到终端。如果随机值为负数,则不执行任何操作。如果只有一个表达式,则大括号是可选的。

else 关键字

我们可以使用 else 关键字来创建一个简单的分支。如果 if 关键字后面的方括号内的表达式的计算结果为假,则会自动执行 else 关键字后面的语句。

Main.java
import java.util.Random;

void main() {

    var r = new Random();
    int num = r.nextInt();

    if (num > 0) {

        System.out.println("The number is positive");

    } else {

        System.out.println("The number is negative");
    }
}

执行 if 关键字后面的块,或者执行 else 关键字后面的块。

if (num > 0) {

    System.out.println("The number is positive");

} else {

    System.out.println("The number is negative");
}

else 关键字位于 if 代码块的右大括号之后。它有自己的代码块,由一对大括号括起来。

$ java Main.java
The number is positive
$ java Main.java
The number is negative
$ java Main.java
The number is negative

使用 if else 的多个分支

我们可以使用 else if 关键字来创建多个分支。当且仅当前一个条件不满足时,else if 关键字才会测试另一个条件。请注意,我们可以在测试中使用多个 else if 关键字。

之前的程序有一个小问题。零被赋予负值。以下程序将解决此问题。

Main.java
import java.util.Scanner;

void main() {

    System.out.print("Enter an integer:");

    try (var sc = new Scanner(System.in)) {
        
        int num = sc.nextInt();

        if (num < 0) {

            System.out.println("The integer is negative");
        } else if (num == 0) {

            System.out.println("The integer equals to zero");
        } else {

            System.out.println("The integer is positive");
        }
    }
}

我们从用户那里接收一个值,如果它是一个负数、正数,或者它等于零,则测试它。

System.out.print("Enter an integer:");

将提示输入整数的信息写入标准输出。

Scanner sc = new Scanner(System.in);
int num = sc.nextInt();

使用 java.util 包的 Scanner 类,我们从标准输入读取一个整数值。

if (num < 0) {

    System.out.println("The integer is negative");
} else if (num == 0) {

    System.out.println("The integer equals to zero");
} else {

    System.out.println("The integer is positive");
}

如果第一个条件计算结果为真,例如,输入的值小于零,则执行第一个代码块,并跳过其余两个代码块。如果未满足第一个条件,则检查 if else 关键字后面的第二个条件。如果第二个条件计算结果为真,则执行第二个代码块。如果不是,则执行 else 关键字后面的第三个代码块。如果未满足先前的条件,则始终执行 else 代码块。

$ java Main.java
Enter an integer:4
The integer is positive
$ java Main.java
Enter an integer:0
The integer equals to zero
$ java Main.java
Enter an integer:-3
The integer is negative

switch 语句

switch 语句是一个选择控制流语句。它允许变量或表达式的值通过多路分支来控制程序执行的流程。与使用 ifelse if 语句的组合相比,它以更简单的方式创建多个分支。每个分支都以 break 关键字结束。

我们使用一个变量或一个表达式。switch 关键字用于根据值列表测试变量或表达式中的值。值列表由 case 关键字表示。如果值匹配,则执行 case 后面的语句。有一个可选的 default 语句。如果没有找到其他匹配项,则执行该语句。

Main.java
import java.util.Scanner;

void main() {

    System.out.print("Enter a domain:");

    try (var sc = new Scanner(System.in)) {

        String domain = sc.nextLine();
        domain = domain.trim().toLowerCase();

        switch (domain) {

            case "us":
                System.out.println("United States");
                break;

            case "de":
                System.out.println("Germany");
                break;

            case "sk":
                System.out.println("Slovakia");
                break;

            case "hu":
                System.out.println("Hungary");
                break;

            default:
                System.out.println("Unknown");
                break;
        }
    }
}

要求用户输入域名。读取域名并将其存储在变量中。使用 switch 关键字根据选项列表测试该变量。在我们的程序中,我们有一个域名变量。我们从命令行读取变量的值。我们使用 case 语句来测试变量的值。有几个选项。例如,如果该值等于 "us",则将字符串 "United States" 打印到控制台。

try (var sc = new Scanner(System.in)) {

    String domain = sc.nextLine();

从控制台读取用户的输入。

domain = domain.trim().toLowerCase();

trim 方法从变量中剥离潜在的前导和尾随空格。toLowerCase 将字符转换为小写。现在 "us"、"US" 或 "us " 都是美国域名的可行选项。

switch (domain) {
    ...
}

在圆括号中,switch 关键字接受一个要测试的输入。输入可以是 byteshortcharintenumString 数据类型。switch 关键字的主体放置在一对大括号内。在主体内部,我们可以放置多个 case 选项。每个选项都以 break 关键字结尾。

case "us":
    System.out.println("United States");
    break;

在此 case 选项中,我们测试域名变量是否等于 "us" 字符串。如果为真,我们将消息打印到控制台。该选项以 break 关键字结尾。如果成功评估了一个选项,则 break 关键字终止 switch 代码块。

default:
    System.out.println("Unknown");
    break;

default 关键字是可选的。如果未评估任何 case 选项,则执行 default 部分。

$ java Main.java
Enter a domain:us
United States

switch 表达式

Java switch 表达式简化了原始 switch 语句。它允许使用称为 arm 的多个 case 标签。

Main.java
import java.util.Scanner;

void main() {

    System.out.print("Enter a domain: ");

    try (var sc = new Scanner(System.in)) {

        String domain = sc.nextLine();
        domain = domain.trim().toLowerCase();

        switch (domain) {

            case "us" -> System.out.println("United States");
            case "de" -> System.out.println("Germany");
            case "sk" -> System.out.println("Slovakia");
            case "hu" -> System.out.println("Hungary");
            default -> System.out.println("Unknown");
        }
    }
}

之前的 switch 语句示例使用 switch 表达式重写。

case "us" -> System.out.println("United States");

switch 表达式使用 -> 将标签与语句分开。不需要 break 语句,一旦匹配到一个选项,就不会评估其他选项。


Switch 表达式可以返回值。

Main.java
import java.util.Scanner;

void main() {

    System.out.print("Enter a domain: ");

    try (var sc = new Scanner(System.in)) {

        String domain = sc.nextLine();
        domain = domain.trim().toLowerCase();

        String res = switch (domain) {

            case "us" -> "United States";
            case "de" -> "Germany";
            case "sk" -> "Slovakia";
            case "hu" -> "Hungary";
            default -> "Unknown";
        };

        System.out.println(res);
    }
}

这是先前示例的修改版本。现在 arm 返回一个字符串值,稍后将其打印。

while 语句

while 语句是一个控制流程语句,允许根据给定的布尔条件重复执行代码。

while (expression) {

    statement;
}

while 关键字执行大括号括起来的块内的语句。只要表达式的计算结果为 true,就会执行这些语句。

Main.java
void main() {

    int i = 0;
    int sum = 0;

    while (i < 10) {

        i++;
        sum += i;
    }

    System.out.println(sum);
}

在代码示例中,我们计算某个数字范围内值的总和。

while 循环有三个部分:初始化、测试和更新。语句的每次执行都称为一个循环。

int i = 0;

我们初始化 i 变量。它用作计数器。

while (i < 10) {
    ...
}

while 关键字后面的圆括号内的表达式是第二阶段,即测试。主体中的语句将一直执行,直到表达式的计算结果为假。

i++;

while 循环的最后阶段是更新。我们增加计数器。请注意,不正确地处理 while 循环可能会导致无限循环。

$ Main.java
55

该程序计算 0, 1, ..., 9 值的总和。

有一个 while 语句的修改版本。它是 do while 语句。即使不满足条件,也可以保证至少运行一次块内的语句。

Main.java
void main() {

    int count = 0;

    do {
        System.out.println(count);
    } while (count != 0);
}

首先执行该块,然后评估真值表达式。在我们的例子中,不满足条件,并且 do while 语句终止。

for 语句

如果在启动循环之前知道循环次数,我们可以使用 for 语句。在此构造中,我们声明一个计数器变量,该变量在循环的每次重复期间自动增加或减少。

Main.java
void main() {

    for (int i = 0; i < 10; i++) {

        System.out.println(i);
    }
}

在此示例中,我们将数字 0..9 打印到控制台。

for (int i = 0; i < 10; i++) {

    System.out.println(i);
}

for 循环有三个阶段。首先,我们将计数器 i 初始化为零。此阶段仅完成一次。接下来是条件。如果满足条件,则执行 for 代码块内的语句。然后是第三个阶段:计数器增加。现在我们重复第 2 阶段和第 3 阶段,直到不满足条件并且 for 循环终止。在我们的例子中,当计数器 i 等于 10 时,for 循环停止执行。

for 循环可用于轻松遍历数组。从数组的 length 属性中,我们知道数组的大小。

Main.java
void main() {

    String[] planets = { "Mercury", "Venus", "Earth",
            "Mars", "Jupiter", "Saturn", "Uranus", "Pluto" };

    for (int i = 0; i < planets.length; i++) {

        System.out.println(planets[i]);
    }

    System.out.println("In reverse:");

    for (int i = planets.length - 1; i >= 0; i--) {

        System.out.println(planets[i]);
    }
}

我们有一个数组,其中包含太阳系中行星的名称。使用两个 for 循环,我们按升序和降序打印值。

for (int i = 0; i < planets.length; i++) {

    System.out.println(planets[i]);
}

数组通过从零开始的索引进行访问。第一个项目的索引为 0。因此,i 变量初始化为零。该条件检查 i 变量是否小于数组的长度。在最后阶段,i 变量递增。

for (int i = planets.length - 1; i >= 0; i--) {

    System.out.println(planets[i]);
}

此 for 循环以相反的顺序打印数组的元素。i 计数器初始化为数组大小。由于索引基于零,因此最后一个元素的索引为数组大小 - 1。该条件确保计数器大于或等于零。(数组索引不能为负数)。在第三步中,i 计数器递减 1。

可以将更多表达式放置在 for 循环的初始化和迭代阶段。

Main.java
import java.util.Arrays;
import java.util.Random;

void main() {

    var r = new Random();

    int[] values = new int[10];
    int num;
    int sum = 0;

    for (int i = 0; i < 10; i++, sum += num) {

        num = r.nextInt(10);
        values[i] = num;
    }

    System.out.println(Arrays.toString(values));
    System.out.println("The sum of the values is " + sum);
}

在我们的示例中,我们创建一个包含十个随机数的数组。计算数字的总和。

for (int i = 0; i < 10; i++, sum += num) {

    num = r.nextInt(10);
    values[i] = num;
}

在 for 循环的第三部分中,我们有两个表达式,用逗号字符分隔。i 计数器递增,并将当前数字添加到 sum 变量。

$ java Main.java
[1, 9, 2, 9, 0, 9, 8, 5, 5, 3]
The sum of the values is 51

增强型 for 语句

增强型 for 语句简化了对数据集合的遍历。它没有显式计数器。该语句逐个遍历数组或集合,并将当前值复制到构造中定义的变量。

Main.java
void main() {

    String[] planets = {
            "Mercury", "Venus", "Earth",
            "Mars", "Jupiter", "Saturn", "Uranus", "Pluto"
    };

    for (String planet : planets) {

        System.out.println(planet);
    }
}

在此示例中,我们使用增强型 for 语句遍历行星数组。

for (String planet : planets) {

    System.out.println(planet);
}

for 语句的用法很简单。行星是我们要遍历的数组。planet 是具有数组当前值的临时变量。for 语句遍历所有行星并将它们打印到控制台。

$ java Main.java
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Pluto

break 语句

break 语句可用于终止由 whileforswitch 语句定义的块。

Main.java
import java.util.Random;

void main() {

    var random = new Random();

    while (true) {

        int num = random.nextInt(30);
        System.out.print(num + " ");

        if (num == 22) {

            break;
        }
    }

    System.out.print('\n');
}

我们定义一个无限 while 循环。我们使用 break 语句来跳出此循环。我们选择一个 1 到 30 的随机值并打印它。如果该值等于 22,我们将完成无限 while 循环。

while (true) {
    ...
}

将 true 放入 while 语句的括号中会创建一个无限循环。我们必须自己终止循环。请注意,此类代码容易出错。我们应该小心使用此类循环。

if (num == 22) {

    break;
}

当随机选择的值等于 22 时,执行 break 语句并终止 while 循环。

$ java Main.java
23 12 0 4 13 16 6 12 11 9 24 23 23 19 15 26 3 3 27 28 25 3 3 25 6 22
$ java Main.java
23 19 29 27 3 28 2 2 26 0 0 24 17 4 7 12 8 20 22
$ java Main.java
15 20 10 25 2 19 26 4 13 21 15 21 21 24 3 22

continue 语句

continue 语句用于跳过循环的一部分,并继续循环的下一次迭代。它可以与 forwhile 语句结合使用。

在以下示例中,我们打印一个无法被 2 整除而没有余数的数字列表。

Main.java
void main() {

    int num = 0;

    while (num < 100) {

        num++;

        if (num % 2 == 0) {
            continue;
        }

        System.out.print(num + " ");
    }

    System.out.print('\n');
}

我们使用 while 循环迭代数字 1..99。

if (num % 2 == 0) {
    continue;
}

如果表达式 num % 2 返回 0,则表示所讨论的数字可以被 2 整除。执行 continue 语句并跳过循环的其余部分。在我们的例子中,循环的最后一条语句被跳过,并且该数字未打印到控制台。开始下一次迭代。

来源

Java 控制流语句 - 教程

在本文中,我们讨论了控制流结构。我们涵盖了 ifif elseelsewhileswitchforbreakcontinue 语句。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有Java教程