目录
概述:
1. 顺序语句
2. 分支语句
2.1 if语句
2.2 if...else语句
2.3 if...else if...else if...else语句
2.4 switch...case default语句及其最佳实践
3. 循环语句
3.1 for循环
3.2 while循环
3.3 循环语句中的break语句和continue语句
4. 总结与最佳实践
4.1 三大流程控制语句核心要点总结
顺序语句
分支语句
循环语句
4.2 最佳实践建议
选择合适的分支语句
循环语句的选择策略
代码质量与可维护性
实际项目中的应用建议
4.3 常见错误与调试技巧
常见错误
调试技巧
概述:
原则上,计算机程序都是从上到下顺序被执行的。但是,在程序执行过程中,可能会因为某些条件的变化跳过某些语句的执行,或者因为某种原因需要重复执行某些语句。为了控制计算机程序执行的过程或者走向,需要使用程序设计语言中的流程控制语句。
本章将详细介绍 Java 中的流程控制语句,包括顺序语句、分支语句、循环语句、数组以及新版 JDK 中switch表达式和yield关键字的使用。
1. 顺序语句
顺序语句,是指用一对大括号“{ }”括起来的从上到下逐条顺序被执行的一组语句。第2章介绍的所有例子程序,都是顺序语句的例子。
// 示例代码:顺序语句演示 public static void main(String[] args) { String name = "张三"; int age = 20; System.out.println("我的名字叫" + name); System.out.println("我今年" + age + "岁"); }实际应用示例:用户注册流程通常就是顺序语句的典型应用,从接收用户输入、验证数据、保存到数据库、发送确认邮件,每一步都是按顺序执行的。
2. 分支语句
程序在顺序执行过程中,需要检查某些变量的值,并根据变量值的不同执行不同的程序语句。Java的分支流程控制语句包括if语句、if...else语句、if...else if...else if...else语句、switch...case default语句等。下面对分支流程语句进行逐个介绍。
2.1 if语句
if语句,顾名思义,就是程序在运行过程中根据不同条件执行不同的语句。
// 示例代码:if语句基本用法 import java.util.Scanner; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int student_in_class; System.out.print("请输入班级人数:"); student_in_class = sc.nextInt(); if (student_in_class >= 50) { System.out.println("这个班的学生人数超过50人!"); } System.out.println("信息显示完毕!"); }更多示例:
// 检查用户权限 boolean isAdmin = true; if (isAdmin) { System.out.println("欢迎管理员登录系统"); showAdminPanel(); } // 验证用户输入 String input = getUserInput(); if (input != null && !input.isEmpty()) { processInput(input); }if分支语句的一般格式如下:
2.2 if...else语句
在if语句中,有时需要根据if语句的条件表达式的true或者false执行不同的代码。
// 示例代码:if...else语句 import java.util.Scanner; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int student_in_class; System.out.print("请输入班级人数:"); student_in_class = sc.nextInt(); if (student_in_class >= 30) { System.out.println("这个班的学生人数超过30人!"); } else { System.out.println("这个班的学生人数少于30人!"); } System.out.println("信息显示完毕!"); }实际应用示例:
// 用户登录验证 String username = "admin"; String password = "123456"; if (isValidUser(username, password)) { System.out.println("登录成功!"); redirectToHomePage(); } else { System.out.println("用户名或密码错误!"); showLoginError(); } // 成绩等级判断 int score = 85; if (score >= 90) { System.out.println("优秀"); } else if (score >= 80) { System.out.println("良好"); } else if (score >= 60) { System.out.println("及格"); } else { System.out.println("不及格"); }if...else语句的一般格式:
2.3 if...else if...else if...else语句
if...else语句可以组合起来构成更为复杂的if...else if...else if...else语句,用于处理多个条件分支。
// 示例代码:多条件判断 import java.util.Scanner; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int student_in_class; System.out.print("请输入班级人数:"); student_in_class = sc.nextInt(); if (student_in_class >= 30) { System.out.println("这个班的学生人数超过30人!"); } else if (student_in_class >= 20) { System.out.println("这个班的学生人数少于30人但是多于20人!"); } else if (student_in_class >= 10) { System.out.println("这个班的学生人数少于20人但是多于10人!"); } else { System.out.println("这个班的学生人数少于10人!"); } System.out.println("信息显示完毕!"); }最佳实践:
- 将最可能成立的条件放在前面,提高效率
- 避免过多的嵌套,超过3层建议使用switch或策略模式
- 使用大括号{}明确代码块范围,即使只有一行代码
if...else if...else if...else语句的一般格式是:
2.4 switch...case default语句及其最佳实践
switch语句,也称为“多分支语句”。它用于检查某个变量的值,如果这个变量的值与某个case语句后面的值相等,则执行这个case后面的语句。如果这个值不等于任何case的值,则执行default后面的语句。
// 示例代码:传统switch语句 import java.util.Scanner; public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入一个单词:"); String str = sc.nextLine(); switch (str) { case "hello": System.out.println("你说:" + "hello"); System.out.println("我说:你好!"); break; case "world": System.out.println("你说:" + "world"); System.out.println("我说:中国!"); break; default: System.out.println("I don't know!"); break; } System.out.println("Over!"); }Java 12+ switch表达式示例:
// 示例代码:新版switch表达式(Java 12+) import java.util.Scanner; public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入一个单词:"); String str = sc.nextLine(); // 使用箭头语法,自动break switch (str) { case "hello" -> { System.out.println("你说:" + "hello"); System.out.println("我说:你好!"); } case "world" -> { System.out.println("你说:" + "world"); System.out.println("我说:中国!"); } default -> System.out.println("I don't know!"); } System.out.println("Over!"); }更多实用示例:
// 月份天数判断 int month = 2; int year = 2024; int days = switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> 31; case 4, 6, 9, 11 -> 30; case 2 -> { if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) { yield 29; // 闰年 } else { yield 28; // 平年 } } default -> throw new IllegalArgumentException("无效月份: " + month); }; System.out.println(month + "月有" + days + "天"); // 用户角色权限检查 String userRole = "ADMIN"; String permission = switch (userRole) { case "ADMIN" -> "所有权限"; case "EDITOR" -> "编辑和查看权限"; case "VIEWER" -> "仅查看权限"; default -> "无权限"; }; System.out.println("用户权限:" + permission);switch...case default语句的一般形式是:
注意事项:
switch语句有一个容易让程序员产生bug的地方:如果在某个case子句中,本来需要使用break语句跳出switch语句,可能由于粗心忘记了break从而导致继续执行该case子句紧接着的case子句代码(这称为"case穿透")。新版JDK对switch语句的使用方法(语法)做了简化:使用“->”这种新的switch...case结构,Java会在每个“->”所对应的代码末尾自动加上break语句,从而解决程序员容易忘记break语句的问题。
最佳实践:
- 总是包含default分支,处理未预料的情况
- 使用Java 12+的箭头语法避免case穿透
- 对于复杂的逻辑,考虑使用多态或策略模式替代
- switch表达式可以返回值,使代码更简洁
3. 循环语句
有时需要一段代码被重复执行,例如,为了进行从1到100的加法运算,需要不断地执行加法运算。为此,需要使用循环语句。Java常用的循环语句包括for循环和while循环。
3.1 for循环
先看一个例子。这个例子计算从1到100的平方和,完成计算后,将结果显示在屏幕上。代码如下:
// 计算1到100的平方和 public static void main(String[] args) { int total = 0; for(int i = 1; i <= 100; i++) { total = total + i * i; // 累加平方 } System.out.println("从1到100的平方和是:" + total); }更多for循环示例:
// 遍历数组 int[] numbers = {1, 2, 3, 4, 5}; for (int i = 0; i < numbers.length; i++) { System.out.println("第" + (i + 1) + "个元素:" + numbers[i]); } // 嵌套循环打印乘法表 for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(j + "×" + i + "=" + (i * j) + "\t"); } System.out.println(); } // 增强for循环(for-each) String[] fruits = {"苹果", "香蕉", "橙子", "葡萄"}; for (String fruit : fruits) { System.out.println("水果:" + fruit); }for循环的一般形式是:
for循环的执行过程是:
第一步:先执行“初始化语句”;
第二步:判断“条件表达式”是否为true,若是,则执行大括号里面的循环体语句;否则,跳出for循环,直接进入第四步;
第三步:执行“迭代语句”,并再次进入第二步;
第四步:执行for循环大括号后面的语句。
如果for循环的大括号里面只有一条语句,则大括号是可以省略的。
3.2 while循环
使用while循环,可以实现与for循环同样的效果。
// 使用while循环计算1到100的平方和 public static void main(String[] args) { int total = 0; int i = 1; while(i <= 100) { total = total + i * i; i++; } System.out.println("从1到100的平方和是:" + total); }更多while循环示例:
// 用户输入验证 import java.util.Scanner; Scanner scanner = new Scanner(System.in); int number; System.out.print("请输入一个正数:"); while (true) { if (scanner.hasNextInt()) { number = scanner.nextInt(); if (number > 0) { break; } } System.out.print("输入无效,请重新输入一个正数:"); scanner.next(); // 清除无效输入 } System.out.println("你输入的正数是:" + number); // 文件读取 BufferedReader reader = new BufferedReader(new FileReader("data.txt")); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close();while循环的一般形式是:
while循环的执行过程:
第一步:检查“条件表达式”是否为true;
第二步:如果“条件表达式”结果为true,则执行大括号里面的循环体语句,之后再进入第一步;
第三步:如果“条件表达式”结果为false,则跳出while循环,进入第四步;
第四步:执行while循环大括号后面的语句。
while循环中,当大括号里面只有一条语句时,可以省略大括号。
3.3 循环语句中的break语句和continue语句
break语句,简单地说,就是终止当前循环语句,使程序跳出循环体(所谓“循环体”,是指循环语句中由大括号括起来的所有语句)直接执行循环语句大括号后面的语句;continue语句,则是跳过循环体中的“continue”语句后面的语句,直接进入下一次循环。
// break和continue示例 public static void main(String[] args) { int i = 0; while(i <= 50) { i++; if (i % 2 == 0) // 如果是偶数 continue; // 跳过本次循环的剩余部分 int cube = i * i * i; // 计算立方 System.out.println(i + "的立方是:" + cube); if (cube > 1000) // 如果立方超过1000 break; // 终止循环 } System.out.println("循环结束!"); }更多break和continue示例:
// break在嵌套循环中的应用4. 总结与最佳实践
4.1 三大流程控制语句核心要点总结
顺序语句
核心要点:
- 程序默认的执行方式,从上到下逐条执行
- 用大括号{}将一组语句组织成代码块
- 适用于线性、无分支的业务逻辑
分支语句
核心要点:
- if语句:最基本的条件判断,根据布尔表达式决定是否执行某段代码
- if...else语句:二选一的分支结构,根据条件执行不同的代码块
- if...else if...else语句:多条件分支,按顺序检查条件,执行第一个为真的分支
- switch...case语句:基于特定值的多分支选择,适合离散值的匹配
循环语句
核心要点:
- for循环:明确知道循环次数时使用,包含初始化、条件判断、迭代三个部分
- while循环:条件满足时持续执行,适合不确定循环次数的场景
- break语句:立即终止当前循环,跳出循环体
- continue语句:跳过本次循环剩余代码,直接进入下一次循环
4.2 最佳实践建议
选择合适的分支语句
- 简单条件判断:使用if语句
- 二选一场景:使用if...else语句
- 多条件判断:
- 条件数量少(2-3个):使用if...else if...else
- 条件数量多且基于离散值:优先使用switch语句
- 条件复杂或需要范围判断:使用if...else if...else
- switch语句适用场景:
- 基于枚举值、字符串或整数的多分支选择
- Java 12+推荐使用箭头语法避免case穿透
- 需要返回值时使用switch表达式
循环语句的选择策略
- 已知循环次数:优先使用for循环,结构清晰
- 未知循环次数:使用while循环,特别是需要先判断条件再执行的情况
- 至少执行一次:考虑使用do...while循环(本文未涉及但值得了解)
- 遍历集合或数组:优先使用增强for循环(for-each)
代码质量与可维护性
- 避免深层嵌套:if/switch嵌套不要超过3层,超过时应考虑重构
- 使用大括号:即使只有一行代码,也使用大括号明确代码块范围
- 条件表达式清晰:复杂的条件判断应提取为布尔变量或方法
- switch最佳实践:
- 总是包含default分支处理未预料情况
- Java 12+使用箭头语法避免忘记break
- 复杂的switch逻辑考虑使用多态或策略模式替代
- 循环控制:
- 避免无限循环,确保循环条件最终会变为false
- 合理使用break和continue,但不要滥用
- 嵌套循环时考虑性能影响
实际项目中的应用建议
- 业务逻辑分层:将复杂的条件判断封装到独立的方法中
- 使用设计模式:对于复杂的分支逻辑,考虑使用策略模式、状态模式等
- 代码可读性:为复杂的条件或循环添加注释说明
- 性能考虑:
- 将最可能成立的条件放在前面
- 避免在循环条件中进行复杂计算
- 考虑循环展开等优化技术(在性能关键路径上)
- 测试覆盖:确保所有分支和循环路径都有相应的测试用例
4.3 常见错误与调试技巧
常见错误
- 忘记break语句:在传统switch语句中导致case穿透
- 条件表达式错误:使用赋值运算符=而不是比较运算符==
- 无限循环:忘记更新循环控制变量
- 边界条件错误:循环次数多一次或少一次
- 空指针异常:在条件判断前未检查对象是否为null
调试技巧
- 使用调试器:单步执行观察程序流程
- 添加日志:在关键分支和循环处输出日志
- 边界测试:测试边界条件和特殊情况
- 代码审查:请同事检查复杂的条件逻辑
- 单元测试:为每个分支和循环路径编写测试用例
总结:流程控制语句是编程的基础,合理使用顺序、分支和循环语句可以构建出清晰、高效、可维护的程序。在实际开发中,应根据具体场景选择最合适的控制结构,并遵循最佳实践,同时注意避免常见错误。随着Java语言的发展,新的语法特性(如switch表达式)也为我们提供了更简洁、安全的编码方式。