网站公告

本次更新:没啥更新的

“钱塘江上潮信起,今日方知我是我”

Skip to content

流程控制 ​

字数: 0 字 时长: 0 分钟

1. 概述 ​

流程控制语句用于控制程序代码的执行顺序。

在默认情况下,Java 程序会按照代码从上到下依次执行。但在实际开发中,我们经常需要根据不同的条件执行不同的代码,或者让某段代码重复执行多次,这就需要使用流程控制语句。

Java 中常见的流程控制主要可以分为三类:

  1. 条件判断

    根据条件是否成立,决定执行哪一段代码。

    常见语句包括:

    • if
    • if-else
    • if-else-if
    • 嵌套 if
    • switch
  2. 循环控制

    在满足指定条件的情况下,重复执行一段代码。

    常见语句包括:

    • for
    • for-each
    • while
    • do-while
  3. 跳转控制

    用于改变循环或代码块原本的执行流程。

    常见语句包括:

    • break:结束当前循环或 switch
    • continue:跳过本次循环,继续执行下一次循环

流程控制是程序实现判断、循环和业务逻辑的基础,也是 Java 语法中最常用的内容之一。

2. if-else ​

image-20250227222824982

1)if 语句 ​

if 语句的格式如下:

java
if(布尔表达式){  
// 如果条件为 true,则执行这块代码
}

画个流程图表示一下:

image-20250227222931850

来写个示例:

java
int age = 20;
if (age < 30) {
    System.out.println("青春年华");
}

输出:

text
青春年华

2)if-else 语句 ​

if-else 语句的格式如下:

java
if(布尔表达式){  
// 条件为 true 时执行的代码块
}else{  
// 条件为 false  时执行的代码块
}

画个流程图表示一下:

image-20250227223219326

来写个示例:

java
int age = 31;

// 判断 age 是否小于 30
// 当前 age = 31,条件不成立,因此执行 else 代码块
if (age < 30) {
    System.out.println("青春年华");
} else {
    System.out.println("而立之年");
}

if-else 用于处理二选一的条件判断。当 if 条件为 true 时执行 if 代码块,否则执行 else 代码块。

输出:

java
而立之年

除了这个例子之外,还有一个判断闰年(被 4 整除但不能被 100 整除或者被 400 整除)的例子:

java
int year = 2020;

// 判断当前年份是否为闰年
// 闰年规则:
// 1. 能被 4 整除,但不能被 100 整除
// 2. 或者能够被 400 整除
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
    System.out.println("闰年");
} else {
    System.out.println("普通年份");
}

判断闰年时,需要同时结合 %、&& 和 ||。满足“能被 4 整除且不能被 100 整除”,或者“能被 400 整除”中的任意一个条件,即为闰年。

输出:

text
闰年

如果执行语句比较简单的话,可以使用三元运算符来代替 if-else 语句,如果条件为 true,返回 ? 后面 : 前面的值;如果条件为 false,返回 : 后面的值。

java
int num = 13;

// 使用三元运算符判断 num 是偶数还是奇数
// num % 2 == 0 为 true 时返回“偶数”
// 否则返回“奇数”
String result = (num % 2 == 0) ? "偶数" : "奇数";

// 当前 num = 13,因此输出“奇数”
System.out.println(result);

输出:

text
奇数

3)if-else-if 语句 ​

if-else-if 语句的格式如下:

java
if(条件1){  
// 条件1 为 true 时执行的代码
}else if(条件2){  
// 条件2 为 true 时执行的代码
}  
else if(条件3){  
// 条件3 为 true 时执行的代码
}  
...  
else{  
// 以上条件均为 false 时执行的代码
}

画个流程图表示一下:

image-20250227223639275

写个示例:

java
int age = 31;

// 多条件判断:会从上到下依次判断
// 一旦某个条件成立,就执行对应代码块,后续条件不再判断
if (age < 30) {
    System.out.println("青春年华");
} else if (age >= 30 && age < 40) {

    // 当前 age = 31,满足 30 <= age < 40
    // 因此执行这里
    System.out.println("而立之年");

} else if (age >= 40 && age < 50) {
    System.out.println("不惑之年");
} else {
    System.out.println("知天命");
}

if-else-if 适合处理多个互斥条件。程序会按照从上到下的顺序依次判断,当某个条件为 true 时,执行对应代码块并结束整个判断结构。

输出:

text
而立之年

4)if 嵌套语句 ​

if 嵌套语句的格式如下:

java
if(外侧条件){    
     // 外侧条件为 true 时执行的代码 
    if(内侧条件){  
        // 内侧条件为 true 时执行的代码
    }    
}

画个流程图表示一下:

image-20250227223838375

来写个示例:

java
int age = 20;
boolean isBoy = true;

// 嵌套 if:先判断年龄条件,再判断性别条件
// 只有外层和内层条件都成立时,才会执行最终代码
if (age >= 20) {

    // 当前 age = 20,外层条件成立
    if (isBoy) {

        // 当前 isBoy = true,内层条件也成立
        System.out.println("男人法定结婚年龄");
    }
}

嵌套 if 是在一个 if 代码块中继续进行条件判断。只有外层条件成立后,程序才会继续判断内层条件。

输出:

text
男人法定结婚年龄

3. switch 语句 ​

switch 语句用来判断变量与多个值之间的相等性。变量的类型可以是:

  • byte、short、char、int:基本整数类型。

  • String:字符串类型。

  • 枚举类型:自定义的枚举类型。

  • 包装类:如 Byte、Short、Character、Integer。

来看一下 switch 语句的格式:

java
switch(变量) {    
	case 可选值1:    
	 // 可选值1匹配后执行的代码;    
	 break;  // 该关键字是可选项
case 可选值2:    
	 // 可选值2匹配后执行的代码;    
	 break;  // 该关键字是可选项
......    
    
default: // 该关键字是可选项     
	 // 所有可选值都不匹配后执行的代码 
}
  • 变量可以有 1 个或者 N 个值。

  • 值类型必须和变量类型是一致的,并且值是确定的。

  • 值必须是唯一的,不能重复,否则编译会出错。

  • break 关键字是可选的,如果没有,则执行下一个 case,如果有,则跳出 switch 语句。

  • default 关键字也是可选的。

画个流程图:

image-20250227224445984

来个示例:

java
int age = 20;

// switch 会根据 age 的值,与各个 case 依次匹配
switch (age) {

    // 当前 age = 20,因此匹配该分支
    case 20:
        System.out.println("上学");

        // break 用于结束当前 switch,避免继续执行后续 case
        break;

    case 24:
        System.out.println("工作");
        break;

    case 30:
        System.out.println("结婚");
        break;

    // 当前面的 case 都不匹配时,执行 default
    default:
        System.out.println("未知");

        // default 位于最后时,break 可以省略
        break;
}

switch 适合对一个固定值进行多分支匹配。每个 case 表示一种可能的取值,break 用于结束当前 switch,否则可能继续执行后续分支。

输出

text
上学

当两个值要执行的代码相同时,可以把要执行的代码写在下一个 case 语句中,而上一个 case 语句中什么也没有。

来看一下示例:

java
String name = "kerwim";

// switch 支持 String 类型,会根据字符串内容匹配对应的 case
switch (name) {

    case "姚明":
        System.out.println("篮球运动员");
        break;

    case "C罗":
        System.out.println("足球运动员");
        break;

    // 多个 case 可以共用同一段处理逻辑
    // name 为 "kerwim" 或 "kevin" 时,都会执行下面的代码
    case "kerwim":
    case "kevin":
        System.out.println("睡觉运动员");
        break;

    // 当前面的 case 都没有匹配时,执行 default
    // 这里选择主动抛出异常,表示出现了不支持的名字
    default:
        throw new IllegalArgumentException("名字没有匹配项");
}

输出:

java
睡觉运动员

枚举作为 switch 语句的变量也很常见,来看例子:

java
public enum PlayerTypes {
    TENNIS,
    FOOTBALL,
    BASKETBALL,
    UNKNOWN
}

public static void main(String[] args) {

    // 传入 BASKETBALL 枚举值
    // createPlayer() 会根据不同的运动员类型返回对应结果
    System.out.println(createPlayer(PlayerTypes.BASKETBALL));
}

private static String createPlayer(PlayerTypes playerType) {

    // switch 可以直接匹配枚举类型
    switch (playerType) {

        case TENNIS:
            return "网球运动员费德勒";

        case FOOTBALL:
            return "足球运动员C罗";

        // 当前传入的是 BASKETBALL,因此会执行这里
        case BASKETBALL:
            return "篮球运动员姚明";

        // UNKNOWN 表示未知类型,这里主动抛出异常
        case UNKNOWN:
            throw new IllegalArgumentException("未知运动员类型");

        // 理论上用于处理未覆盖的情况
        default:
            throw new IllegalArgumentException(
                    "不支持的运动员类型:" + playerType
            );
    }
}

switch 支持枚举类型。使用枚举配合 switch 可以避免直接使用字符串或数字作为类型标识,使代码语义更加清晰,也更容易维护。

输出:

text
篮球运动员姚明

但 switch 不支持 long、float、double 类型,这是因为:

  • long 是 64 位整数,不在 switch 一开始设计的范围内(32 位的 int 在大多数情况下就够用了)。

  • float 和 double 是浮点数,浮点数的比较不如整数简单和直接,存在精度误差。

4. for 循环 ​

image-20250227225159052

1)普通 for 循环 ​

普通的 for 循环可以分为 4 个部分:

1)初始变量:循环开始执行时的初始条件。

2)条件:循环每次执行时要判断的条件,如果为 true,就执行循环体;如果为 false,就跳出循环。当然了,条件是可选的,如果没有条件,则会一直循环。

3)循环体:循环每次要执行的代码块,直到条件变为 false。

4)自增/自减:初始变量变化的方式。

来看一下普通 for 循环的格式:

java
for(初始变量;条件;自增/自减){  
	// 循环体
}

画个流程图:

来个示例:

java
// for 循环通常用于已知循环次数的场景
// 初始化:int i = 0,只执行一次
// 条件判断:i < 5,每次循环开始前都会判断
// 迭代操作:i++,每次循环结束后执行
for (int i = 0; i < 5; i++) {

    // i 的取值依次为 0、1、2、3、4
    System.out.println("我是第" + i + "次循环");
}

for 循环由初始化、循环条件、迭代操作三部分组成。当循环条件为 true 时执行循环体,随后执行迭代操作,再继续下一次判断。这里一共执行 5 次循环。

再来一个:

java
// 外层循环控制行数
// i 的取值依次为 0、1、2、3、4,共执行 5 次
for (int i = 0; i < 5; i++) {

    // 内层循环控制每一行输出 ❤ 的数量
    // j 从 0 开始,当 j <= i 时继续循环
    // 因此每一行会比上一行多输出一个 ❤
    for (int j = 0; j <= i; j++) {
        System.out.print("❤");
    }

    // 当前行输出完成后换行
    System.out.println();
}

这是一个典型的嵌套 for 循环。外层循环控制行数,内层循环控制每一行输出的内容数量,最终效果是每一行比上一行多一个 ❤。

输出:

java
❤
❤❤
❤❤❤
❤❤❤❤
❤❤❤❤❤

2)for-each ​

for-each 循环通常用于遍历数组和集合,它的使用规则比普通的 for 循环还要简单,不需要初始变量,不需要条件,不需要下标来自增或者自减。来看一下语法:

java
for(元素类型 元素 : 数组或集合){  
	// 要执行的代码
}

来看一下示例:

java
public static void demo03() {

    String[] strs = {"kerwim", "一个 Java 开发社畜"};

    // 增强 for 循环(for-each)
    // 每次循环都会从 strs 数组中取出一个元素,并赋值给 str
    for (String str : strs) {

        // 依次输出数组中的每个字符串
        System.out.println(str);
    }
}

增强 for 循环适合遍历数组或集合,不需要手动维护索引。每次循环都会自动取出一个元素,代码通常比普通 for 循环更简洁。

输出:

text
kerwim
一个Java开发社畜

3)无限 for 循环 ​

来个示例:

java
// 无限 for 循环
// 初始化、循环条件和迭代操作都被省略
// 因为没有结束条件,所以循环会一直执行
for (;;) {

    // 这行代码会不断重复输出
    System.out.println("停不下来。。。。");
}

for (;;) 表示一个无限循环,效果类似 while (true)。如果循环体中没有 break、return 或异常等终止逻辑,程序会一直执行下去。

就会一直输出停不下来,只有你手动停掉程序,这个其实没有多大意义,但是谁的程序人生又没写过几次死循环呢?

5. while 循环 ​

来看一下 while 循环的格式:

java
while(条件){  
	//循环体  
}

画个流程图:

image-20250301134512993

来个示例:

java
int i = 0;

// while(true) 表示无限循环
// 需要在循环内部通过 break、return 等方式结束循环
while (true) {

    System.out.println("kerwim");

    // 每执行一次循环,i 加 1
    i++;

    // 当 i 等于 5 时结束循环
    // 因此 "kerwim" 一共会输出 5 次
    if (i == 5) {
        break;
    }
}

while (true) 本身不会自动结束,通常需要在循环内部设置退出条件,并通过 break 终止循环。

然后会输出五次 kerwim

java
kerwim
kerwim
kerwim
kerwim
kerwim

写个无限 while 循环

java
// while(true) 表示无限循环
// 条件始终为 true,因此循环会一直执行
while (true) {

    // 这行代码会不断重复输出
    System.out.println("停不下来。。。。");
}

while (true) 是最常见的无限循环写法之一。如果循环体内部没有 break、return 或异常等终止逻辑,程序会一直执行下去。

输出:

java
停不下来。。。。
停不下来。。。。
停不下来。。。。
停不下来。。。。

把 while 的条件设置为 true,并且循环体中没有 break 关键字的话,程序一旦运行起来,就根本停不下来了,除非强制停止。

6. do-while 循环 ​

来看一下 do-while 循环的格式:

java
do{  
	// 循环体
}while(条件);

画个流程图:

image-20250301134809174

来个示例:

java
int i = 0;

// do-while 会先执行一次循环体,再判断循环条件
do {

    System.out.println("kerwim");

    // 每执行一次循环,i 加 1
    i++;

    // 当 i 等于 5 时结束循环
    // 因此 "kerwim" 一共会输出 5 次
    if (i == 5) {
        break;
    }

} while (true);

do-while 与 while 的区别在于:do-while 会先执行一次循环体,再判断条件,所以循环体至少会执行一次。这里虽然条件始终为 true,但通过 break 在第 5 次循环时结束。

输出:

java
kerwim
kerwim
kerwim
kerwim
kerwim

无限 do-while 循环

java
// do-while 无限循环
// 会先执行一次循环体,然后判断 while 中的条件
// 由于条件始终为 true,因此循环会一直执行
do {

    // 这行代码会不断重复输出
    System.out.println("停不下来。。。。");

} while (true);

do-while 会先执行循环体,再判断条件。这里条件始终为 true,因此如果没有 break、return 或异常等终止逻辑,循环会一直执行。

输出:

java
停不下来。。。。
停不下来。。。。
停不下来。。。。
停不下来。。。。

把 do-while 的条件设置为 true,并且循环体中没有 break 关键字的话,程序一旦运行起来,就根本停不下来了,除非强制停止。

image-20250301135019320

7. break ​

break 关键字通常用于中断循环或 switch 语句,它在指定条件下中断程序的当前流程。如果是内部循环,则仅中断内部循环。

可以将 break 关键字用于所有类型循环语句中,比如说 for 循环、while 循环,以及 do-while 循环。

来画个流程图感受一下:

image-20250301135159419

用在 for 循环中的示例:

java
// break 用于立即结束当前循环
for (int i = 1; i <= 10; i++) {

    // 当 i 等于 5 时,直接跳出整个 for 循环
    if (i == 5) {
        break;
    }

    // 因此这里只会输出 1、2、3、4
    System.out.println(i);
}

break 会直接结束当前循环,不再继续执行后续循环。因此当 i == 5 时,循环立即终止。

用在嵌套 for 循环中的示例:

java
// 外层循环控制 i,内层循环控制 j
for (int i = 1; i <= 3; i++) {

    for (int j = 1; j <= 3; j++) {

        // 当 i = 2 且 j = 2 时
        // break 只会结束当前所在的内层循环
        if (i == 2 && j == 2) {
            break;
        }

        System.out.println(i + " " + j);
    }
}

在嵌套循环中,break 默认只会结束它所在的那一层循环,不会直接结束外层循环。

用在 while 循环中的示例:

java
int i = 1;

// while 循环会在每次执行前判断 i <= 10
while (i <= 10) {

    // 当 i 等于 5 时进入该分支
    if (i == 5) {

        // 先将 i 加 1,此时 i 变为 6
        i++;

        // break 立即结束整个 while 循环
        break;
    }

    // 因此这里只会输出 1、2、3、4
    System.out.println(i);

    // 每次循环结束前,i 加 1
    i++;
}

break 会立即结束当前 while 循环。这里当 i == 5 时直接退出,因此最终只会输出 1、2、3、4。break 前面的 i++ 实际上不会影响后续循环,因为循环已经结束了。

用在 do-while 循环中的示例:

java
int j = 1;

// do-while 会先执行循环体,再判断循环条件
do {

    // 当 j 等于 5 时进入该分支
    if (j == 5) {

        // 先将 j 加 1,此时 j 变为 6
        j++;

        // break 立即结束整个 do-while 循环
        break;
    }

    // 因此这里只会输出 1、2、3、4
    System.out.println(j);

    // 每次循环结束前,j 加 1
    j++;

} while (j <= 10);

break 会立即结束当前 do-while 循环。这里当 j == 5 时直接退出,因此最终只会输出 1、2、3、4。break 前面的 j++ 对后续循环没有实际作用,因为循环已经终止。

用在 switch 语句中的示例:

java
// switch 会根据 age 的值匹配对应的 case
switch (age) {

    case 20:
        System.out.println("上学");

        // break 用于结束当前 switch,避免继续执行后续 case
        break;

    case 24:
        System.out.println("苏州工作");
        break;

    case 30:
        System.out.println("洛阳工作");
        break;

    // 当前面的 case 都没有匹配时,执行 default
    default:
        System.out.println("未知");

        // default 位于最后时,break 可以省略
        break;
}

switch 会根据变量的值匹配对应的 case。匹配成功后执行对应代码,通常使用 break 结束当前分支,避免继续执行后续 case。

8. continue ​

当我们需要在 for 循环或者 (do)while 循环中立即跳转到下一个循环时,就可以使用 continue 关键字,通常用于跳过指定条件下的循环体,如果循环是嵌套的,仅跳过当前循环。

来个示例:

java
// continue 用于跳过当前这一次循环
for (int i = 1; i <= 10; i++) {

    // 当 i 等于 5 时,跳过本次循环
    // 后面的代码不会执行,直接进入下一次循环
    if (i == 5) {
        continue;
    }

    // 因此最终会输出 1~10,但不会输出 5
    System.out.println(i);
}

continue 不会结束整个循环,而是只跳过当前这一次循环,继续执行下一次循环。这里当 i == 5 时,5 会被跳过。

输出:

java
1
2
3
4
6
7
8
9
10

再来个循环嵌套的例子。

java
// 外层循环控制 i,内层循环控制 j
for (int i = 1; i <= 3; i++) {

    for (int j = 1; j <= 3; j++) {

        // 当 i = 2 且 j = 2 时,跳过当前这一次内层循环
        // 不会结束循环,而是继续执行 j = 3
        if (i == 2 && j == 2) {
            continue;
        }

        System.out.println(i + " " + j);
    }
}

在嵌套循环中,continue 默认只作用于它所在的当前循环。这里会跳过 2 2,但内层循环和外层循环都会继续执行。

输出:

java
1 1
1 2
1 3
2 1
2 3
3 1
3 2
3 3

2 2 没有输出,被跳过了。

再来看一下 while 循环时 continue 的使用示例:

java
int i = 1;

// while 循环会在每次执行前判断 i <= 10
while (i <= 10) {

    // 当 i 等于 5 时,跳过本次循环
    if (i == 5) {

        // 先将 i 加 1,避免一直停留在 5 造成死循环
        i++;

        // 跳过本次循环后续代码,直接进入下一次 while 判断
        continue;
    }

    // 因此最终会输出 1~10,但不会输出 5
    System.out.println(i);

    // 每次正常循环结束后,i 加 1
    i++;
}

在 while 循环中使用 continue 时,要特别注意循环变量的更新。这里必须先执行 i++,否则当 i == 5 时会不断进入 continue,导致死循环。

输出:

java
1
2
3
4
6
7
8
9
10

注意:如果把 if 条件中的“i++”省略掉的话,程序就会进入死循环,一直在 continue。

最后,再来看一下 do-while 循环时 continue 的使用示例:

java
int i = 1;

// do-while 会先执行循环体,再判断循环条件
do {

    // 当 i 等于 5 时,跳过本次循环
    if (i == 5) {

        // 先将 i 加 1,避免一直停留在 5
        i++;

        // 跳过本次循环后续代码
        // 然后执行 while 条件判断,再决定是否进入下一轮
        continue;
    }

    // 因此最终会输出 1~10,但不会输出 5
    System.out.println(i);

    // 每次正常循环结束后,i 加 1
    i++;

} while (i <= 10);

在 do-while 中执行 continue 后,会直接跳到末尾的 while 条件判断。这里必须先执行 i++,否则 i == 5 时会不断重复,造成死循环。

输出:

java
1
2
3
4
6
7
8
9
10

注意:同样的,如果把 if 条件中的“i++”省略掉的话,程序就会进入死循环,一直在 continue。

Noctiflorous Garden · MIT License