CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Java 语言基础/课时/条件与循环
RawBlame
课时目录14 节

Java 语言基础

  1. 01Java 与 JVM 是什么
  2. 02基本语法与 main
  3. 03基本类型与引用类型
  4. 04条件与循环
  5. 05方法与参数
  6. 06数组
  7. 07类与封装
  8. 08继承接口与多态
  9. 09集合框架入门
  10. 10字符串
  11. 11异常处理
  12. 12文件 IO 入门
  13. 13Maven 与项目结构
  14. 14综合练习与 dsa-java 分工

条件与循环

if/switch/for/while、break/continue。

30 分钟

条件与循环

这一课你将能做到

  1. 用 if/else、switch(含 JDK 17 箭头语法)表达业务分支,如订单状态流转、权限判断
  2. 用 for/while/增强 for 处理批量数据,正确使用 break/continue 控制流程
  3. 独立写出九九乘法表、数组求最值等经典练习,具备刷算法题的语法基础

为什么要学

顺序执行的代码只能「一条道走到黑」,真实业务全是分支和重复:请求合法性校验走 if,订单状态判断走 switch,批量写库走循环。本站后端的 Service 层,随便一个方法都是「校验参数(if)→ 状态判断(switch)→ 批量处理(for)」的组合。

语法上这一课不难,难点在把业务语言翻译成控制流:「金额大于 0 且用户未封禁才允许下单」→ if (amount > 0 && !user.isBanned())。练的就是这个翻译能力。

先建立图像

控制流三种基本结构:

顺序            分支                循环
──▶──▶──        条件?               ┌─条件成立?─┐
                  ├─true──▶ A       │    ▼      │
                  └─false─▶ B       └──否──▶ 出来
                                  (条件成立就绕回去再干一遍)

跟着做

步骤 1:if / else if / else

新建 ScoreDemo.java:

public class ScoreDemo {
    public static void main(String[] args) {
        int score = 86;

        if (score >= 90) {
            System.out.println("优秀");
        } else if (score >= 80) {
            System.out.println("良好");      // 命中这里
        } else if (score >= 60) {
            System.out.println("及格");
        } else {
            System.out.println("不及格");
        }

        // 多条件组合:&& 与、|| 或、! 非
        int amount = 500;
        boolean vip = true;
        if (amount >= 300 && vip) {
            System.out.println("可用 vip 折扣");  // 短路:amount 不够就不会看 vip
        }
    }
}

步骤 2:switch 传统写法与箭头语法

public class OrderStatusDemo {
    public static void main(String[] args) {
        int status = 2;   // 假设 1=待支付 2=已支付 3=已发货 4=已完成

        // 老写法:容易漏 break 导致「击穿」
        switch (status) {
            case 1:
                System.out.println("待支付");
                break;               // 不写 break,会继续执行下一个 case!
            case 2:
                System.out.println("已支付");
                break;
            default:
                System.out.println("未知状态");
        }

        // JDK 14+ 箭头语法:无击穿,可以直接返回值(本站后端主流写法)
        String desc = switch (status) {
            case 1 -> "待支付";
            case 2 -> "已支付";
            case 3, 4 -> "已" + (status == 3 ? "发货" : "完成");  // 多标签合并
            default -> "未知状态";
        };
        System.out.println(desc);

        // switch 还能作用于 String 和枚举
        String role = "admin";
        switch (role) {
            case "admin" -> System.out.println("管理员权限");
            case "user"  -> System.out.println("普通用户");
            default      -> System.out.println("非法角色");
        }
    }
}

步骤 3:for 循环三件套

public class LoopDemo {
    public static void main(String[] args) {
        // 经典 for:初始化; 条件; 步进
        for (int i = 1; i <= 5; i++) {
            System.out.print(i + " ");     // 1 2 3 4 5
        }
        System.out.println();

        // 累加求和:1 加到 100
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        System.out.println("1+2+...+100 = " + sum);   // 5050

        // 嵌套循环:九九乘法表
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.printf("%d×%d=%-4d", j, i, i * j);
            }
            System.out.println();
        }
    }
}

步骤 4:while / do-while / 增强 for

import java.util.List;

public class WhileDemo {
    public static void main(String[] args) {
        // while:先判断再执行,可能一次都不跑
        int retries = 0;
        while (retries < 3) {
            System.out.println("第 " + (retries + 1) + " 次重试调用下游接口");
            retries++;
        }

        // do-while:先执行再判断,至少跑一次(适合「先提示再校验输入」场景)
        int count = 10;
        do {
            System.out.println("do-while 至少执行一次,count=" + count);
        } while (count < 5);    // 条件为 false 退出,但上面已执行过一次

        // 增强 for(for-each):遍历数组/集合,最常用
        int[] nums = {3, 7, 1, 9};
        int max = nums[0];
        for (int n : nums) {        // 逐个取出元素
            if (n > max) max = n;
        }
        System.out.println("最大值 = " + max);

        // 集合同样适用(第 9 课展开)
        for (String s : List.of("mysql", "redis")) {
            System.out.println("依赖中间件: " + s);
        }
    }
}

步骤 5:break 与 continue

public class BreakDemo {
    public static void main(String[] args) {
        int[] ids = {101, 102, -1, 104};   // -1 表示脏数据

        for (int id : ids) {
            if (id == -1) {
                System.out.println("遇到脏数据,终止处理");
                break;         // 跳出整个循环
            }
            if (id % 2 == 0) {
                continue;      // 跳过本次,直接进入下一轮
            }
            System.out.println("处理奇数 id: " + id);   // 只打印 101
        }

        // 带标签的 break:一次跳出多层嵌套(少用,知道即可)
        outer:
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (i * j == 2) break outer;   // 直接跳出外层
                System.out.printf("(%d,%d) ", i, j);
            }
        }
        System.out.println();
    }
}

讲清楚要点

  1. 条件必须是 boolean:Java 不接受 if (1)、if (x = 5) 这种 C 风格写法,if (x = 5) 直接编译报错——误用 = 代替 == 会被编译器拦住。
  2. switch 击穿是老写法最大坑:漏 break 会顺势执行后面所有 case。箭头语法从根上消灭了这个问题,新代码一律用箭头。
  3. for 三段各有职责:初始化只跑一次、条件每次循环前判断、步进每次循环体后执行。循环变量 i 的作用域仅限循环内。
  4. while 求先判断,do-while 求至少一次:绝大多数场景用 while/for,do-while 只在「必须先做一次」时用。
  5. 增强 for 不能改结构:遍历集合时不能增删元素(会 ConcurrentModificationException),要删就用迭代器或 removeIf。
  6. 死循环有正当用途:while (true) + 内部 break 是「不断轮询直到成功」的标准写法,比如重试逻辑,但必须有退出条件。

你可能会懵的地方

  • i++ 和 ++i 有区别吗? 单独成语句时无区别。作为表达式时有:int a = 5; int b = a++ 得 b=5(先取值再加);int c = 5; int d = ++c 得 d=6(先加再取值)。工程里建议只单独使用,避免炫技。

  • switch 能作用在 long/float 上吗? 不能。传统 switch 只支持 byte/short/char/int、其包装类、枚举和 String(long/float/double/boolean 都不行)。

  • 增强 for 想要下标怎么办? 用普通 for:for (int i = 0; i < arr.length; i++)。需要边遍历边知道位置时只能这么写。

  • 循环里 return 和 break 什么区别? return 直接结束整个方法;break 只结束当前循环。方法里循环后面还有代码时,两者行为不同。

  • 为什么条件判断要「先判 null 再调方法」? if (user != null && user.getAge() > 18) 中 && 短路保证 user 为 null 时不会执行右边的 user.getAge(),避免 NPE。顺序写反了照样炸。

错法对照

错法问题正解
if (x = 5)编译错误:需要 booleanif (x == 5)
switch case 漏 break击穿执行后续 case用箭头语法 case 1 ->
for (int i = 0; i <= arr.length; i++)最后一次越界抛异常条件用 <
循环内 int i 写成循环外声明多个循环共用变量易出错每个循环独立声明,作用域最小化
while (true) 没有退出条件程序卡死内部必须有 break/return/异常出口
if (a == 1); System.out.println("x");分号成空语句,println 恒执行if 后不要随手加分号

卡点急救

  1. 循环打印不出来/只打一行:检查条件是否一开始就为 false(如 i <= 0);确认没有在 if 后多写分号。
  2. 死循环卡住终端:Windows 按 Ctrl + C 终止进程。然后检查步进语句是否写了(漏 i++ 是头号原因)。
  3. ArrayIndexOutOfBoundsException:索引越界。最后访问的合法下标是 length - 1,条件从 <= 改 <。
  4. switch 变量报「不兼容的类型」:检查作用对象,long/double/boolean 不支持,先转成 int 或改用 if。
  5. 嵌套循环缩进对不上:每一层花括号独立缩进 4 空格,IDE 里 Ctrl+Alt+L(IDEA)一键格式化。

面试常问

  • while 和 do-while 的区别? while 先判断后执行,可能零次;do-while 先执行后判断,至少一次。

  • switch 支持哪些类型? byte/short/char/int 及其包装类、枚举、String(JDK 7+)。本质是按 int 比较,包装类自动拆箱——包装类为 null 时会 NPE。

  • break、continue、return 的区别? break 跳出当前循环/switch;continue 跳过本次进入下一轮;return 结束方法。嵌套时作用范围不同,带标签 break 可跳出外层但可读性差。

  • && 与 & 在条件判断中的区别? && 短路与,左 false 则右不执行;& 位运算/非短路,两边都算。判空保护必须用 &&。

  • switch 的箭头语法和传统语法区别?(JDK 新特性题) 箭头语法无击穿、case 可作表达式返回值、可多标签合并、必须穷尽所有分支(配合枚举时编译器检查遗漏)。

自测三问

  1. 传统 switch 漏写 break 会发生什么?箭头语法如何避免这个问题?
  2. 用一个循环求 100 以内所有 7 的倍数之和,写出代码。
  3. for (int i = 0; i <= arr.length; i++) 为什么错?正确写法是什么?

小结一句话

if/switch 负责分岔、for/while 负责重复,break/continue 精确控制循环节奏;新代码用箭头 switch 消灭击穿,判空永远把 null 检查写在 && 左边。

延伸

  • Oracle:控制流语句
  • 下一课:方法与参数——Java 只有值传递?一次讲透重载、可变参数和 static。
加载本节练习…
← 上一课基本类型与引用类型下一课 →方法与参数