Java基础(五):流程控制全解析——分支(if/switch)和循环(for/while)的深度指南

📁 完美体育365软件下载 📅 2025-07-19 06:23:27 👤 admin 👁️ 4275 ❤️ 211
Java基础(五):流程控制全解析——分支(if/switch)和循环(for/while)的深度指南

Java基础系列文章

Java基础(一):发展史、技术体系与JDK环境配置详解

Java基础(二):八种基本数据类型详解

Java基础(三):逻辑运算符详解

Java基础(四):位运算符详解

Java基础(五):if/switch与for/while - 深入理解流程控制

引言 流程控制是编程语言的基石,它决定了代码执行的顺序和路径。Java提供了强大而灵活的流程控制语句,使你能够根据条件执行代码、重复执行任务以及跳出循环。掌握这些结构是写出高效、逻辑清晰程序的关键。

一、分支结构1、if语句语法:

代码语言:javascript代码运行次数:0运行复制if (condition) {

// 当 condition 为 true 时执行的代码块

}执行流程:

计算 condition (必须是一个布尔表达式:true 或 false)如果结果为 true,则执行代码块内的语句如果结果为 false,则跳过代码块,继续执行后面的代码示例:

代码语言:javascript代码运行次数:0运行复制int age = 18;

if (age >= 18) {

System.out.println("你已成年。");

}

// 无论 age 是否 >=18, 这行都会执行

System.out.println("年龄检查完毕。");2、if-else语句语法:

代码语言:javascript代码运行次数:0运行复制if (condition) {

// 当 condition 为 true 时执行的代码块

} else {

// 当 condition 为 false 时执行的代码块

}执行流程:

计算 condition如果 true,执行 if 代码块如果 false,执行 else 代码块两个代码块必选其一执行,且只执行其一示例:

代码语言:javascript代码运行次数:0运行复制int score = 75;

if (score >= 60) {

System.out.println("及格!");

} else {

System.out.println("不及格!");

}3、if-else-if阶梯语法:

代码语言:javascript代码运行次数:0运行复制if (condition1) {

// condition1 为 true 时执行

} else if (condition2) {

// condition1 为 false 且 condition2 为 true 时执行

} else if (condition3) {

// 前面条件都为 false 且 condition3 为 true 时执行

} else {

// 所有条件都为 false 时执行 (可选)

}执行流程:

按顺序检查每个 condition遇到第一个为 true 的 condition,则执行其对应的代码块,然后跳过整个 if-else-if 结构剩余部分如果所有 condition 都为 false,则执行 else 块(如果存在);如果不存在 else,则整个结构不执行任何操作示例:

代码语言:javascript代码运行次数:0运行复制int grade = 85;

if (grade >= 90) {

System.out.println("优秀 (A)");

} else if (grade >= 80) { // 隐含 grade < 90

System.out.println("良好 (B)");

} else if (grade >= 70) { // 隐含 grade < 80

System.out.println("中等 (C)");

} else if (grade >= 60) { // 隐含 grade < 70

System.out.println("及格 (D)");

} else {

System.out.println("不及格 (F)");

}4、switch语句 (传统与现代) 基于一个表达式的值,从多个可能的执行路径中选择一个。适用于多分支选择,尤其当分支基于单个变量或表达式的离散值(整数、字符、字符串 String、枚举 enum)时,通常比 if-else-if 更清晰。

4.1、传统语法 (Java 7 及之前,注意break)代码语言:javascript代码运行次数:0运行复制switch (expression) {

case value1:

// expression 等于 value1 时执行的语句

break; // 跳出 switch 块

case value2:

// expression 等于 value2 时执行的语句

break;

... // 可以有任意多个 case

default:

// 如果 expression 不匹配任何 case 值时执行的语句 (可选)

}expression:可以是 byte, short, int, char (Java 7之前),以及 String (Java 7+), enum

case valueN:valueN 必须是常量表达式,且类型必须与 expression 兼容。每个 case 代表一个可能匹配的值

break:至关重要!它终止当前 case 的执行并跳出整个 switch 块。如果省略 break,程序会继续执行下一个 case 中的语句(无论其值是否匹配),这称为“case穿透(fall-through)”。除非有意设计穿透,否则必须写 break

default:可选的。当没有 case 匹配时执行。可以放在任何位置(开头、中间、结尾),但通常放结尾。不需要 break(如果它是最后一个)

示例 (传统带break):

代码语言:javascript代码运行次数:0运行复制int dayOfWeek = 3;

switch (dayOfWeek) {

case 1:

System.out.println("星期一");

break;

case 2:

System.out.println("星期二");

break;

case 3:

System.out.println("星期三");

break;

case 4:

System.out.println("星期四");

break;

case 5:

System.out.println("星期五");

break;

default:

System.out.println("周末或无效日期");

} // 输出: 星期三示例 (故意 Case 穿透):

代码语言:javascript代码运行次数:0运行复制char grade = 'B';

switch (grade) {

case 'A':

case 'B': // A 或 B 都执行下面的代码

System.out.println("成绩优良");

break;

case 'C':

System.out.println("成绩中等");

break;

case 'D':

case 'F': // D 或 F 都执行下面的代码

System.out.println("需要努力");

break;

default:

System.out.println("无效成绩");

} // 输出: 成绩优良4.2、现代语法 (Java 12+, 使用->箭头和yield)Java 12 引入了更简洁、更安全(避免意外穿透)的 switch 表达式和语句形式::

箭头标签 (case L ->):使用 -> 代替 :。如果标签匹配,则只执行 -> 右侧的表达式或语句块

多值匹配 (case L1, L2 ->):一个 case 可以匹配多个值,用逗号分隔

switch 表达式 (返回值):整个 switch 可以作为一个表达式,使用 yield 返回一个值。必须覆盖所有可能情况(或 default)

示例 (现代 switch 语句,无穿透):

代码语言:javascript代码运行次数:0运行复制int dayOfWeek = 3;

switch (dayOfWeek) {

case 1 -> System.out.println("星期一"); // 单条语句可直接写

case 2 -> System.out.println("星期二");

case 3 -> {

// 多条语句用代码块 {}

System.out.println("星期三");

System.out.println("一周的中点!");

}

case 4, 5 -> System.out.println("临近周末"); // 匹配 4 或 5

default -> System.out.println("周末或无效日期");

} // 输出: 星期三 \n 一周的中点!示例 (switch 表达式,使用 yield 返回值,类似于return):

代码语言:javascript代码运行次数:0运行复制int dayOfWeek = 3;

String dayType = switch (dayOfWeek) {

case 1, 2, 3, 4, 5 -> "工作日";

case 6, 7 -> {

// 代码块中使用 yield 返回值

System.out.println("放假了...");

yield "周末"; // yield 提供 switch 表达式的返回值

}

default -> {

// 代码块中使用 yield 返回值

System.out.println("无效输入: " + dayOfWeek);

yield "未知"; // yield 提供 switch 表达式的返回值

}

}; // 注意:作为表达式,末尾有分号 ';'

System.out.println(dayOfWeek + " 是 " + dayType); // 输出: 3 是 工作日4.3、更高级语法 (Java 17+, 模式匹配预览特性) Java 17 开始引入对 switch 语句的新特性模式匹配,作为预览功能提供。这种特性允许在 switch 的 case 分支中直接进行类型判断和绑定变量,从而让代码更简洁、更安全。

代码语言:javascript代码运行次数:0运行复制static String test(Object obj) {

return switch (obj) {

case String s -> "字符串: " + s;

case Integer i -> "整数: " + i;

case null -> "空值";

default -> "其他类型";

};

}case String s -> …:如果 obj 是一个字符串,就匹配并将其绑定到变量 scase Integer i -> …:同理,匹配整数case null -> …:甚至可以对 null 值进行单独处理default -> …:兜底处理其他类型 注意⚠️:这是预览功能:意味着它还不是 Java 标准的一部分,将来可能会改动,从 Java 21 开始,这一功能有望正式成为标准

二、循环结构1、for循环用途:当循环次数已知或在循环前就知道初始化、条件和迭代步骤时特别适用。结构清晰

传统语法:

代码语言:javascript代码运行次数:0运行复制for (initialization; condition; iteration) {

// 循环体:当 condition 为 true 时重复执行的代码

}initialization (初始化):在循环开始前执行一次。通常用于声明和初始化循环控制变量 (如:int i = 0;)condition (条件):每次循环迭代前检查的布尔表达式。如果 true,执行循环体;如果 false,终止循环iteration (迭代/步进):每次循环体执行后执行。通常用于更新循环控制变量 (如:i++, i = i + 2)执行流程:

执行 initialization (仅一次)计算 condition如果 condition 为 true: 执行循环体执行 iteration回到步骤 2 (再次检查 condition)如果 condition 为 false,循环终止示例:

代码语言:javascript代码运行次数:0运行复制// 打印 0 到 9

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

System.out.println(i);

}

// 计算 1 到 100 的和

int sum = 0;

for (int num = 1; num <= 100; num++) {

sum += num;

}

System.out.println("Sum: " + sum);格式的多样性(多变量控制、省略部分语句)

代码语言:javascript代码运行次数:0运行复制// 省略部分语句(但必须保留分号)

int i = 0;

for ( ; i < 5; i++) {

System.out.println(i);

}

// 多个变量用逗号隔开

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

System.out.println("i = " + i + ", j = " + j);

}2、while循环用途:当循环次数未知,但在循环开始前有一个明确的继续条件时适用。先判断条件,再决定是否执行循环体

语法:

代码语言:javascript代码运行次数:0运行复制while (condition) {

// 循环体:当 condition 为 true 时重复执行的代码

}执行流程:

计算 condition如果 condition 为 true: 执行循环体回到步骤 1 (再次检查 condition)如果 condition 为 false,循环终止特点:循环体可能一次都不执行(如果初始条件就是 false)

示例:

代码语言:javascript代码运行次数:0运行复制int i = 0;

while (i < 5) {

System.out.println(i);

i++;

}3、do-while循环用途:当循环体至少需要执行一次,然后再根据条件决定是否继续时适用。先执行一次循环体,再判断条件

语法:

代码语言:javascript代码运行次数:0运行复制do {

// 循环体:至少执行一次

} while (condition); // 注意结尾的分号执行流程:

执行循环体计算 condition如果 condition 为 true,回到步骤 1如果 condition 为 false,循环终止特点:循环体至少执行一次

示例:

代码语言:javascript代码运行次数:0运行复制// 1.基本用法

int i = 0;

do {

System.out.println(i);

i++;

} while (i < 5);

// 2.条件为假也执行一次

int i = 10;

do {

System.out.println("i = " + i); // 会执行一次

i++;

} while (i < 5);4、增强for循环 (for-each)用途:专门用于遍历数组 和实现了 Iterable 接口的集合 (如 List, Set, Queue)。语法简洁,避免了显式索引操作

语法:

代码语言:javascript代码运行次数:0运行复制for (ElementType element : collectionOrArray) {

// 使用 element 执行操作

}ElementType:集合或数组中元素的类型element:循环变量,在每次迭代中依次被赋值为集合或数组中的当前元素collectionOrArray:要遍历的数组或集合对象执行流程:自动依次从数组或集合中取出每个元素,赋值给 element,并执行循环体。遍历完所有元素后结束

优点:简洁、安全(无需管理索引)、不易出错(避免索引越界)

缺点:不能直接访问当前元素的索引;不能修改集合结构(如删除元素,否则可能引发 ConcurrentModificationException);只能单向顺序遍历

示例:

代码语言:javascript代码运行次数:0运行复制// 1.遍历数组

int[] numbers = {1, 2, 3, 4, 5};

for (int num : numbers) {

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

} // 输出: 1 2 3 4 5

// 2.遍历 List 集合

List fruits = Arrays.asList("Apple", "Banana", "Orange");

for (String fruit : fruits) {

System.out.println(fruit);

} // 输出: Apple \n Banana \n Orange三、流程控制的利器:break和continue1、break语句用途:

在循环中 (for, while, do-while):立即终止其所在的最内层循环,跳出循环体,继续执行循环之后的代码在 switch 中:终止 case 的执行并跳出整个 switch 块(防止穿透)示例 (跳出循环):

代码语言:javascript代码运行次数:0运行复制// 查找数组中第一个负数

int[] nums = {5, 8, -2, 10, 3};

boolean found = false;

for (int num : nums) {

if (num < 0) {

System.out.println("找到负数: " + num);

found = true;

break; // 找到第一个负数后立即跳出循环

}

}

if (!found) {

System.out.println("没有找到负数");

}2、continue语句用途:仅用于循环中。跳过当前迭代中循环体内 continue 语句之后的所有代码,立即进入下一次迭代(检查循环条件并执行步进语句)

示例:

代码语言:javascript代码运行次数:0运行复制// 打印 1 到 10 的奇数

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

if (i % 2 == 0) { // 如果是偶数

continue; // 跳过本次循环剩余部分,直接 i++ 然后检查 i<=10

}

System.out.println(i); // 只有奇数会执行到这里

}

// 输出: 1 \n 3 \n 5 \n 7 \n 93、带标签的break和continue(谨慎使用)用途:用于跳出多层嵌套的循环或语句块

语法:在目标循环或语句块前放置一个标签 (label:), 然后在 break 或 continue 后指定该标签名 (break label; / continue label;)

break label;:立即终止标签所标记的整个循环或语句块

continue label;:立即跳转到标签所标记的循环的下一次迭代开始处(跳过标记循环当前迭代的剩余部分)

示例 (跳出外层循环):

代码语言:javascript代码运行次数:0运行复制outerLoop: // 标签定义在外层 for 循环前

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

innerLoop: // 标签定义在内层 for 循环前

for (int j = 0; j < 5; j++) {

System.out.println("i=" + i + ", j=" + j);

if (i == 2 && j == 2) {

break outerLoop; // 跳出整个 outerLoop (两层循环都终止)

}

}

}

// 当 i=2, j=2 时输出终止,后续 i=3,4 都不再执行 注意:带标签的break/continue会破坏代码结构,使逻辑不易追踪。优先考虑重构代码(如将内层循环提取为方法)来避免使用它们。仅在逻辑清晰且必要时使用。

四、无限循环与空语句1、无限循环定义:循环条件始终为 true 的循环,理论上会一直执行下去

常见形式:

代码语言:javascript代码运行次数:0运行复制// while 形式

while (true) {

// ... 需要某种 break 条件跳出 ...

}

// for 形式

for (;;) { // 初始化、条件、迭代都省略

// ... 需要某种 break 条件跳出 ...

}用途:服务器监听、游戏主循环、需要用户主动退出的程序等。必须在循环体内提供跳出机制(如 break, return, System.exit())

风险:如果缺少跳出机制,程序将永远挂起,消耗CPU资源

2、空语句定义:一个单独的分号 ; 表示一条不执行任何操作的语句

在流程控制中的潜在陷阱:

代码语言:javascript代码运行次数:0运行复制// 意图:i<10 时才打印 i

int i = 0;

while (i < 10); // 注意这里错误地多了一个分号!这是一个空语句循环体。

{

System.out.println(i); // 这行代码在 while 循环块之外!

i++;

}

// 结果:while (i < 10); 是一个无限循环(如果 i<10),因为循环体是空语句 `;`。

// { ... } 只是一个普通的代码块,在无限循环之后(永远执行不到)。 警示:在 if, for, while 的条件后切勿随意加分号 ;,除非你明确需要一个空循环体。这通常是逻辑错误

总结 Java的流程控制语句(分支:if, switch;循环:for, while, do-while, for-each;跳转:break, continue)为你提供了构建程序逻辑的完整工具箱。理解每种结构的语法、执行流程、适用场景和潜在陷阱,并结合清晰编码的最佳实践,是编写健壮、高效、易于维护的Java程序的基础。

相关推荐