# JavaSE 基础 — Day03 笔记 > **日期**:2026-07-15 > **项目**:`c260715` > **作者**:WanJL --- ## 一、流程控制 — switch 分支语句 ### 1. switch 语句概述 `switch` 语句和 `if` 不同,`if` 是**范围的匹配**,而 `switch` 是**针对某个具体值的匹配**。 #### 基本语法格式 ```java switch (变量) { case 常量1: 代码块; break; case 常量2: 代码块; break; case 常量n: 代码块; break; default: 代码块; } ``` **执行流程**: - 如果变量的值和 `case 常量1` 相等,就执行对应的代码块 - 如果和 `case 常量n` 相等,就执行对应代码块 - 如果都不相等,就执行 `default` 中的代码块 - `break` 的作用:在执行完对应的代码块后,跳出整个 switch 结构,后面的代码不再执行 #### 基本示例 ```java int a = 3; switch (a) { case 1: System.out.println("a=1"); break; case 2: System.out.println("a=2"); break; case 3: System.out.println("a=3"); break; default: System.out.println("不知道"); } // 输出:a=3 ``` #### 课堂练习:星期转换 定义一个变量(1~7),使用 switch 判断并分别输出 星期一 ~ 星期日。 ```java int b = 3; switch (b) { 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; case 6: System.out.println("星期六"); break; case 7: System.out.println("星期日"); break; default: System.out.println("不知道"); } ``` --- ### 2. 增强 switch(JDK 17~21) JDK 17~21 引入了增强的 switch 语句,支持: - **任何基本数据类型**、**字符串 String**、**枚举** - **箭头语法 `->`**:更简洁,自带 break 效果(不需要显式写 `break`) - **多值匹配**:一个 case 可以匹配多个值,用逗号分隔 - **switch 表达式**:switch 可以直接返回一个值 #### ① 箭头语法 + 多值匹配 ```java String day = "1"; switch (day) { case "1", "2", "3", "4", "5" -> System.out.println("工作日"); case "6", "7" -> System.out.println("休息日"); } ``` #### ② 箭头语法 + 代码块(多条语句) ```java switch (day) { case "1" -> { System.out.println("星期一"); System.out.println("周一"); System.out.println("天不错"); } case "2" -> System.out.println("星期二"); case "3" -> System.out.println("星期三"); case "4" -> System.out.println("星期四"); case "5" -> System.out.println("星期五"); case "6" -> System.out.println("星期六"); case "7" -> System.out.println("星期日"); } ``` > 如果箭头右侧有多条语句,需要使用 `{ }` 代码块包裹。 #### ③ switch 表达式(返回一个值) switch 可以直接作为一个表达式使用,返回匹配到的值,可用于赋值等操作: ```java String dd = "1"; String s = switch (dd) { case "1" -> "星期一"; case "2" -> "星期二"; case "3" -> "星期三"; case "4" -> "星期四"; case "5" -> "星期五"; case "6" -> "星期六"; case "7" -> "星期日"; default -> "不知道"; }; System.out.println("今天是" + s + ",天气真不错"); // 输出:今天是星期一,天气真不错 ``` > ⚠️ switch 表达式必须要有 `default` 分支,以确保所有可能值都有对应结果。 --- ### 3. 传统 switch vs 增强 switch 对比 | 特性 | 传统 switch | 增强 switch(JDK 17+) | |------|-----------|----------------------| | **语法** | `case 值:` + `break;` | `case 值 ->` 箭头语法 | | **break** | 必须写,否则穿透 | 自带 break,无需写 | | **多值匹配** | 不支持(需写多个 case) | 支持:`case "1","2" ->` | | **返回值** | 不支持 | 支持:`switch(expr) { ... }` | | **穿透效果** | 有(可利用) | 无 | | **可读性** | 一般 | 更简洁清晰 | --- ## 二、流程控制 — 循环结构 ### 1. 循环概述 **循环结构**:满足条件就不停地重复执行某段代码。 Java 提供三种循环结构: | 循环类型 | 特点 | |---------|------| | **`for` 循环** | 先判断,后执行;适用于已知循环次数 | | **`while` 循环** | 先判断,后执行;适用于不确定循环次数 | | **`do...while` 循环** | 先执行,后判断;**循环体至少执行一次** | --- ### 2. for 循环 #### 语法格式 ```java for (初始化语句; 循环条件; 迭代语句) { 循环体; } ``` #### 执行步骤 ``` 第1步:执行初始化语句(如 int i = 0;) 第2步:执行循环条件(如 i < 10;) → 如果结果为 true,执行第3步 → 如果结果为 false,跳转到第5步(结束循环) 第3步:执行循环体(如 System.out.println(i);) 第4步:执行迭代语句(如 i++),然后跳转回第2步 第5步:跳出循环,继续执行后面的代码 ``` #### 示例:循环 1~100 之间的整数 ```java for (int i = 1; i <= 100; i++) { System.out.println(i); } ``` --- ### 3. while 循环 #### 语法格式 ```java 初始化语句; while (循环条件) { 循环体; 迭代语句; } ``` #### 示例:循环 1~100 之间的整数 ```java int i = 1; while (i <= 100) { System.out.println(i); i++; } ``` > ⚠️ **重要**:使用 `while` 或 `do...while` 时,**一定不要忘了写迭代语句(如 `i++`)**,否则会变成**死循环**(无限循环)。 --- ### 4. do...while 循环 #### 语法格式 ```java 初始化语句; do { 循环体; 迭代语句; } while (循环条件); ``` #### 示例:循环 1~100 之间的整数 ```java int i = 1; do { System.out.println(i); i++; } while (i <= 100); ``` #### 三种循环的核心区别 | 特性 | `for` | `while` | `do...while` | |------|-------|---------|-------------| | **判断时机** | 先判断,后执行 | 先判断,后执行 | 先执行,后判断 | | **执行次数** | 0~n 次 | 0~n 次 | **至少 1 次** | | **适用场景** | 已知循环次数 | 不确定循环次数 | 至少需要执行一次 | | **初始化位置** | for 语句内部 | 循环外部 | 循环外部 | --- ### 5. 循环控制语句(结束循环的三种方式) Java 提供了三种方式控制循环的执行流程: | 控制语句 | 作用 | 说明 | |---------|------|------| | **`break`** | 结束整个循环 | 跳出循环体,继续执行循环后面的代码 | | **`continue`** | 结束本轮循环 | 跳过本次循环剩余代码,继续执行下一轮循环 | | **`return`** | 结束整个方法 | 直接结束当前方法,方法中循环后面的代码也不再执行 | #### ① break — 结束整个循环 ```java for (int i = 0; i < 10; i++) { if (i == 3) { break; // i == 3 时结束整个循环 } System.out.println(i); } // 输出:0 1 2 // 循环到此结束,继续执行循环外的代码 System.out.println(".....循环后的代码...."); ``` > `break` 执行后,循环立即终止,程序继续执行循环后面的代码。 #### ② continue — 结束本轮循环 ```java for (int i = 0; i < 10; i++) { if (i == 3) { continue; // i == 3 时跳过本轮,不执行输出 } System.out.println(i); } // 输出:0 1 2 4 5 6 7 8 9 // 注意:没有 3,因为 i==3 时跳过了本次循环 ``` > `continue` 执行后,本轮循环中剩余的代码不再执行,直接进入下一轮迭代(i++ → 判断条件)。 #### ③ return — 结束整个方法 ```java for (int i = 0; i < 10; i++) { if (i == 3) { return; // i == 3 时结束方法,循环后面的代码也不执行了 } System.out.println(i); } // 输出:0 1 2 // 注意:循环后面的所有代码都不会执行 System.out.println(".....循环后的代码...."); // ❌ 不会执行 ``` > `return` 比 `break` 更"狠"——它不仅结束循环,还会直接结束整个 `main` 方法,方法内循环后面的所有代码都不再执行。 #### 三种控制语句对比 | 控制语句 | 影响范围 | 循环剩余代码 | 循环外代码 | 适用场景 | |---------|---------|------------|-----------|---------| | **`break`** | 仅当前循环 | 不执行 | 继续执行 | 找到目标后提前退出循环 | | **`continue`** | 仅本轮循环 | 不执行(跳到下一轮) | 继续执行 | 跳过某些不符合条件的值 | | **`return`** | 整个方法 | 不执行 | 不执行 | 方法执行完毕或异常提前返回 | --- ### 6. 流程控制中的常见陷阱 #### ① 浮点类型精度问题 ```java double a = 0.1 + 0.2; System.out.println(a); // 0.30000000000000004 if (a == 0.3) { System.out.println("相等"); } else { System.out.println("不想等"); } // 输出:不想等 ``` > **原因**:浮点数采用 IEEE 754 标准存储,`0.1 + 0.2` 在计算机中无法精确表示为 `0.3`,而是近似值 `0.30000000000000004`。 #### ② switch 的穿透问题 ```java int x = 2; switch (x) { case 1: case 2: case 3: System.out.println("1~3"); break; } // 输出:1~3 // 如果 case 1、case 2 不加 break,会一直穿透到 case 3 ``` > **穿透技巧**:当多个 case 需要执行相同的代码时,可以利用穿透特性,只在最后一个 case 写 `break`,减少重复代码。 ### 7. while 循环实战练习 #### 练习 1:统计整数位数 给定一个整数 `12345`,使用 `while` 循环统计它有多少位。 ```java /** * @author WanJl * @title Demo04 * @description 课堂练习:统计整数位数 * @create 2026/7/15 */ public class Demo04 { public static void main(String[] args) { int n = 12345; int t = 0; // 统计位数 while (n != 0) { n /= 10; // 每次除以10,缩小10倍 t++; // 每缩小一次,位数累计1 } System.out.println(t); // 输出:5 } } ``` > **核心思路**:一个整数不断除以 10,每除一次就去掉一位,直到变成 0。除的次数就是位数。 > > **for vs while 选择原则**:知道循环次数用 `for`,不知道循环次数用 `while`。此处我们不知道 `12345` 是多少位(不确定除以多少次才到 0),所以适合用 `while`。 #### 练习 2:求各位数字之和 给定一个整数 `12345`,使用 `while` 循环求其各位数字之和(1 + 2 + 3 + 4 + 5 = 15)。 ```java /** * @author WanJl * @title Demo05 * @description 课堂练习:求各位数字之和 * @create 2026/7/15 */ public class Demo05 { public static void main(String[] args) { int n = 12345; int sum = 0; // 累加和 while (n != 0) { sum += n % 10; // 获取个位数字,累加到 sum n /= 10; // 去掉个位,缩小10倍 } System.out.println(sum); // 输出:15 } } ``` > **核心思路**: > 1. `n % 10` — 每次取个位数字 > 2. `n / 10` — 去掉个位,继续取下一个数字 > 3. 循环直到 `n` 变成 0 --- ### 8. 嵌套循环(Nested Loop) **嵌套循环**就是循环里面再放一个循环。 ```java for (int i = 0; i < 10; i++) { // 外层循环 System.out.println("i=" + i); for (int j = 0; j < 10; j++) { // 内层循环 System.out.print("j=" + j); } System.out.println(); } ``` **执行规律**:外层循环执行**一轮**,内层循环完整执行**一次**。 > 内层循环总共执行的次数 = 外层循环次数 × 内层循环次数 #### 练习 3:打印矩形星号图案(4 行 5 列) ```java /** * @author WanJl * @title Demo06 * @description 课堂练习:打印4行5列矩形星号 * @create 2026/7/15 */ public class Demo06 { public static void main(String[] args) { for (int i = 0; i < 4; i++) { // 外层:控制行数 for (int j = 0; j < 5; j++) { // 内层:控制每行星号个数 System.out.print("*"); // 不换行 } System.out.println(); // 一行结束,换行 } } } // 输出: // ***** // ***** // ***** // ***** ``` #### 练习 4:打印空心矩形星号图案(5 行 5 列) ```java /** * @author WanJl * @title Demo07 * @description 课堂练习:打印5行5列空心矩形星号 * @create 2026/7/15 */ public class Demo07 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { // 外层:控制行数 for (int j = 1; j <= 5; j++) { // 内层:控制列数 // 第1行、第5行:全部输出 * // 第2~4行:第1列和第5列输出 *,其余输出空格 if (i == 1 || i == 5) { System.out.print("*"); } else { if (j == 1 || j == 5) { System.out.print("*"); } else { System.out.print(" "); } } } System.out.println(); // 换行 } } } // 输出: // ***** // * * // * * // * * // ***** ``` #### 练习 5:打印菱形星号图案(5 行) ```java /** * @author WanJl * @title Demo08 * @description 课堂练习:打印5行菱形星号图案 * @create 2026/7/15 */ public class Demo08 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { for (int j = 1; j <= 5; j++) { if (i == 3) { // 第3行:全星号 System.out.print("*"); } else { if (i == 1 || i == 5) { // 第1、5行:中间星号 if (j == 3) { System.out.print("*"); } else { System.out.print(" "); } } else if (i == 2 || i == 4) { // 第2、4行:两侧星号 if (j == 1 || j == 5) { System.out.print(" "); } else { System.out.print("*"); } } } } System.out.println(); } } } // 输出: // * // *** // ***** // *** // * ``` > **嵌套循环 + 条件判断**是解决二维图形打印问题的核心思路: > - 外层循环控制**行数** > - 内层循环控制**列数** > - `if` 判断决定某个位置输出 `*` 还是空格 --- ## 三、数组(Array) ### 1. 数组概述 **数组**是一种用来存储多个相同类型数据的容器。 #### Java 数据类型回顾 Java 中的数据类型分为两类: | 类型 | 说明 | |------|------| | **基本数据类型** | byte、short、int、long、float、double、char、boolean | | **引用数据类型** | 类(class)、**数组([])**、接口(interface)、枚举(enum)、注解(@interface) | > 之前学过的 `String` 就是引用数据类型(类),现在学习的**数组**也是引用数据类型。 #### 数组的特点 | 特点 | 说明 | |------|------| | ① 连续存储 | 数组中的每个元素(值)存储在连续的内存空间中 | | ② 通过索引访问 | 使用索引值(下标)来访问数组中的元素 | | ③ 固定长度 | 数组有一个 `length` 属性,表示数组的长度,创建后不能改变 | | ④ 同类型 | 数组中只能存储同一种类型的元素 | | ⑤ 指定类型 | 创建数组时必须指定要存储的元素类型 | | ⑥ 索引从 0 开始 | 第一个元素的索引为 `0`,最后一个元素的索引为 `length - 1` | --- ### 2. 定义数组的格式 ```java 数据类型[] 数组名; ``` 示例: ```java int[] a; // 声明一个 int 类型的数组变量 a ``` > `int[] a` 表示 `a` 是一个 int 类型的数组变量,为它赋值时对应的数组必须是整数类型。 --- ### 3. 数组的初始化 数组的初始化分为两种方式:**动态初始化** 和 **静态初始化**。 #### ① 动态初始化 程序员负责**定义数组长度**,计算机负责**为数组元素赋默认值**。 ```java // 语法:数组变量名 = new 数组类型[数组长度]; int[] a = new int[10]; ``` **各类型元素的默认值:** | 元素类型 | 默认值 | |---------|-------| | `byte`、`short`、`int`、`long` | `0` | | `float`、`double` | `0.0` | | `char` | ``(空字符) | | `boolean` | `false` | | 引用数据类型 | `null` | #### 数组在内存中的地址 ```java int[] a = new int[10]; System.out.println(a); // 输出类似:[I@b4c966a ``` > 地址值含义: > - `[` — 表示这是一个一维数组 > - `I` — 表示元素类型为 int > - `@` — 分隔符 > - `b4c966a` — 数组在堆内存中的地址值(十六进制) #### ② 静态初始化 程序员负责**为数组元素赋值**,计算机负责**计算数组的长度**。 **完整语法:** ```java int[] arr1 = new int[]{1, 3, 5, 7, 9, 6, 2, 4}; ``` **简写语法(最常用):** ```java int[] arr2 = {1, 3, 5, 7, 9, 6, 2, 4}; ``` --- ### 4. 数组元素的访问与赋值 #### 为数组元素赋值 ```java 数组名[索引值] = 值; // 示例 arr[0] = 1; // 直接赋一个字面量 int x = 15; arr[1] = x; // 赋一个变量的值 ``` #### 访问(读取)数组元素 ```java 数组名[索引值] // 示例 System.out.println(arr[0]); // 输出第一个元素(已被赋值为 1) System.out.println(arr[1]); // 输出第二个元素(已被赋值为 15) System.out.println(arr[2]); // 输出第三个元素(未赋值,输出默认值 0) ``` #### 使用 for 循环遍历数组 ```java for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } ``` > `arr.length` — 获取数组的长度(元素个数) #### 索引越界风险 ```java int[] arr = new int[5]; System.out.println(arr[5]); // ❌ 索引越界!ArrayIndexOutOfBoundsException // 索引范围:0 ~ length-1,即 0 ~ 4 ``` > ⚠️ 访问数组元素时,索引值必须在 **0 ~ length-1** 之间,否则会抛出 `ArrayIndexOutOfBoundsException`(数组下标索引异常)。 --- ### 5. 数组初始化方式对比 | 特性 | 动态初始化 | 静态初始化 | |------|-----------|-----------| | **谁指定长度** | 程序员 | 计算机(根据元素个数自动计算) | | **谁赋值** | 计算机(默认值) | 程序员(手动指定) | | **语法** | `new int[10]` | `new int[]{1,2,3}` 或 `{1,2,3}` | | **适用场景** | 暂时不知道元素的具体值 | 已知元素的具体值 | --- ## 四、课后作业讲解(7月14日作业) ### 题目 1:判断闰年 **知识点**:if-else、逻辑运算符(`&&`、`||`)、算术运算符(`%`) **闰年规则**(满足其一即可): 1. 能被 4 整除但不能被 100 整除 2. 能被 400 整除 **代码实现**: ```java /** * @author WanJl * @version 1.0 * @title HomeWork05 * @description 7月14日课后作业-判断年份 * @create 2026/7/15 */ public class HomeWork01 { public static void main(String[] args) { int year = 2000; // 判断是否闰年:能被4整除且不能被100整除,或者能被400整除 if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { System.out.println(year + "是闰年"); } else { System.out.println(year + "是平年"); } } } ``` > **核心逻辑**:`year % 4 == 0 && year % 100 != 0 || year % 400 == 0` --- ### 题目 2:三个数比大小 **知识点**:三目运算符嵌套 **代码实现**: ```java /** * @author WanJl * @version 1.0 * @title HomeWord02 * @description 7月14日课后作业-三个数比大小 * @create 2026/7/15 */ public class HomeWork02 { public static void main(String[] args) { int a = 10, b = 15, c = 20; // 三目运算符嵌套:先比较 a 和 b,再将结果与 c 比较 System.out.println(a > b ? (a > c ? a : c) : (b > c ? b : c)); } } ``` > **核心逻辑**:`a > b ? (a > c ? a : c) : (b > c ? b : c)` > - 先判断 `a > b` 是否成立 > - 如果成立,再比较 `a` 和 `c`,取较大值 > - 如果不成立,再比较 `b` 和 `c`,取较大值 --- ### 题目 4:水仙花数判定 **知识点**:算术运算符(`/`、`%`)、if-else **水仙花数**:一个三位数,其各位数字的立方和等于该数本身。例如:`153 = 1³ + 5³ + 3³` **代码实现**: ```java /** * @author WanJl * @version 1.0 * @title HomeWork04 * @description 7月14日课后作业-水仙花数 * @create 2026/7/15 */ public class HomeWork04 { public static void main(String[] args) { int number = 153; // 定义一个整数变量 int bai = number / 100; // 百位 int shi = number / 10 % 10; // 十位 int ge = number % 10; // 个位 if (number == bai * bai * bai + shi * shi * shi + ge * ge * ge) { System.out.println(number + "是水仙花数"); } else { System.out.println(number + "不是水仙花数"); } } } ``` > **取位技巧**: > - 百位:`number / 100`(整除去掉后两位) > - 十位:`number / 10 % 10`(先整除去掉个位,再取余去掉百位以上) > - 个位:`number % 10`(取余去掉前三位) --- ### 题目 5:简易计算器 **知识点**:if-else if-else 多分支、算术运算符、除零判断 **代码实现**: ```java /** * @author WanJl * @version 1.0 * @title HomeWork05 * @description 7月14日课后作业-简易计算器 * @create 2026/7/15 */ public class HomeWork05 { public static void main(String[] args) { int a = 15, b = 20; char operator = '/'; if (operator == '+') { System.out.println(a + b); } else if (operator == '-') { System.out.println(a - b); } else if (operator == '*') { System.out.println(a * b); } else if (operator == '/') { if (b == 0) { System.out.println("除数不能为0"); } else { System.out.println(a / b); } } else if (operator == '%') { if (b == 0) { System.out.println("除数不能为0"); } else { System.out.println(a % b); } } } } ``` > ⚠️ **注意**:做除法和取模运算时,必须先判断除数是否为 0,避免 `ArithmeticException` 异常。 --- ### 题目 7:数字加密系统 **知识点**:算术运算符(`/`、`%`)、变量交换算法、综合运用 **加密规则**: 1. 获取 4 位数的每一位 2. 每个数字加 5 3. 对 10 取余 4. 第 1 位与第 4 位互换,第 2 位与第 3 位互换 **代码实现**: ```java /** * @author WanJl * @version 1.0 * @title HomeWork07 * @description 7月14日课后作业-数字加密系统 * @create 2026/7/15 */ public class HomeWork07 { public static void main(String[] args) { int number = 1234; // 加密规则-0:获取每个位的数 int qian = number / 1000; // 千位 int bai = number / 100 % 10; // 百位 int shi = number / 10 % 10; // 十位 int ge = number % 10; // 个位 // 加密规则-1:每个数字加 5 qian += 5; bai += 5; shi += 5; ge += 5; // 加密规则-2:对 10 取余 qian %= 10; bai %= 10; shi %= 10; ge %= 10; // 加密规则-3:第1位和第4位互换,第2位和第3位互换(使用加减法交换) qian = qian + ge; ge = qian - ge; qian = qian - ge; bai = bai + shi; shi = bai - shi; bai = bai - shi; System.out.println("加密结果:" + qian + bai + shi + ge); } } ``` > **变量交换技巧**(不借助第三个变量): ```java a = a + b; // a 变成两数和 b = a - b; // b 得到原 a 的值 a = a - b; // a 得到原 b 的值 ``` --- ## 五、知识拓展 ### 1. break 在 switch 中的作用 在传统 switch 中,`break` 用于**跳出 switch 结构**,防止**穿透(fall-through)**。 ```java int n = 2; switch (n) { case 1: System.out.println("A"); // 没有 break → 会继续执行 case 2 case 2: System.out.println("B"); break; // 跳出 switch case 3: System.out.println("C"); } // 输出:B(case 1 不会匹配,case 2 匹配后输出 B 后跳出) ``` > 如果不写 `break`,匹配到某个 case 后,其后的所有 case 都会被执行,直到遇到 `break` 或 switch 结束。这个特性有时也会被**利用**(如多个 case 共享同一段代码)。 ### 2. 死循环 循环条件永远为 `true` 的循环称为**死循环**(无限循环),应避免出现: ```java // 死循环示例(不要运行!) while (true) { System.out.println("无限循环"); } // for 的死循环写法 for (;;) { System.out.println("无限循环"); } ``` ### 3. 整数的进制表示 Java 中整数可以使用不同进制表示: | 前缀 | 进制 | 示例 | 十进制值 | |------|------|------|---------| | `0b` 或 `0B` | 二进制 | `0b1100` | 12 | | `0` | 八进制 | `014` | 12 | | 无前缀 | 十进制 | `12` | 12 | | `0x` 或 `0X` | 十六进制 | `0xC` | 12 | ```java int bin = 0b1100; // 二进制 → 12 int oct = 014; // 八进制 → 12 int dec = 12; // 十进制 → 12 int hex = 0xC; // 十六进制 → 12 ``` --- ## 六、完整代码汇总 ### Demo01.java — switch 分支语句 ```java /** * @author WanJl * @version 1.0 * @title Demo01 * @description 流程控制-分支语句-switch * @create 2026/7/15 */ public class Demo01 { public static void main(String[] args) { /* switch语句和if不一样,不是范围的匹配,而是针对某个值的匹配,格式: switch(变量){ case 常量1: 代码块; break; case 常量2: 代码块; break; case 常量n: 代码块; break; default: 代码块; } */ // ===== 传统 switch ===== int a = 3; switch (a) { case 1: System.out.println("a=1"); break; case 2: System.out.println("a=2"); break; case 3: System.out.println("a=3"); break; default: System.out.println("不知道"); } // ===== 练习题:星期转换 ===== int b = 3; switch (b) { 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; case 6: System.out.println("星期六"); break; case 7: System.out.println("星期日"); break; default: System.out.println("不知道"); } // ===== 增强 switch:箭头语法 + 多值匹配 ===== String day = "1"; switch (day) { case "1", "2", "3", "4", "5" -> System.out.println("工作日"); case "6", "7" -> System.out.println("休息日"); } // ===== 增强 switch:箭头语法 + 代码块 ===== switch (day) { case "1" -> { System.out.println("星期一"); System.out.println("周一"); System.out.println("天不错"); } case "2" -> System.out.println("星期二"); case "3" -> System.out.println("星期三"); case "4" -> System.out.println("星期四"); case "5" -> System.out.println("星期五"); case "6" -> System.out.println("星期六"); case "7" -> System.out.println("星期日"); } // ===== switch 表达式(返回值) ===== String dd = "1"; String s = switch (dd) { case "1" -> "星期一"; case "2" -> "星期二"; case "3" -> "星期三"; case "4" -> "星期四"; case "5" -> "星期五"; case "6" -> "星期六"; case "7" -> "星期日"; default -> "不知道"; }; System.out.println("今天是" + s + ",天气真不错"); } } ``` ### Demo02.java — 循环结构 + 流程控制陷阱 ```java /** * @author WanJl * @version 1.0 * @title Demo02 * @description 流程控制-循环结构 * @create 2026/7/15 */ public class Demo02 { public static void main(String[] args) { /* 循环结构:满足条件就不停地循环执行代码 Java 三种循环结构: for循环: for(初始化语句; 循环条件; 迭代语句) { 循环体; } 执行步骤: 1. 执行初始化语句 2. 执行循环条件(true 继续,false 退出) 3. 执行循环体 4. 执行迭代语句,跳回第2步 while循环: 初始化语句; while(循环条件) { 循环体; 迭代语句; } do...while循环: 初始化语句; do { 循环体; 迭代语句; } while(循环条件); do...while 至少执行一次循环体 */ // ========== 流程控制中的陷阱 ========== // 陷阱 1:浮点类型精度问题 double a = 0.1 + 0.2; System.out.println(a); // 0.30000000000000004 if (a == 0.3) { System.out.println("相等"); } else { System.out.println("不想等"); } // 陷阱 2:switch 的穿透问题 // 如果不加 break,case 会一直穿透 int x = 2; switch (x) { case 1: case 2: case 3: System.out.println("1~3"); break; } } } ``` ### Demo03.java — 循环控制语句(break / continue / return) ```java /** * @author WanJl * @version 1.0 * @title Demo03 * @description 结束循环的语句 * @create 2026/7/15 */ public class Demo03 { public static void main(String[] args) { /* 有 3 种方式可以结束循环 break; 结束循环,继续执行循环后面的代码 continue; 结束本轮循环,继续执行下一轮循环 return; 结束方法,顺便结束循环 */ // ===== continue:结束本轮循环 ===== for (int i = 0; i < 10; i++) { if (i == 3) { continue; // i==3 时跳过本轮,不输出 3 } System.out.println(i); } // 输出:0 1 2 4 5 6 7 8 9 System.out.println("---------------------------------------"); // ===== break:结束整个循环 ===== for (int i = 0; i < 10; i++) { if (i == 3) { break; // i==3 时结束整个循环 } System.out.println(i); } // 输出:0 1 2 System.out.println(".....循环后的代码...."); System.out.println("---------------------------------------"); // ===== return:结束整个方法 ===== for (int i = 0; i < 10; i++) { if (i == 3) { return; // i==3 时结束方法,循环后的代码也不执行 } System.out.println(i); } // 输出:0 1 2 // 以下代码不会执行! System.out.println(".....循环后的代码...."); } } ``` ### Demo04.java — while 循环实战:统计整数位数 ```java /** * @author WanJl * @version 1.0 * @title Demo04 * @description 课堂练习:统计整数位数 * @create 2026/7/15 */ public class Demo04 { public static void main(String[] args) { int n = 12345; int t = 0; // 统计位数 while (n != 0) { n /= 10; // 每次除以10,缩小10倍 t++; // 每缩小一次,位数累计1 } System.out.println(t); // 输出:5 } } ``` ### Demo05.java — while 循环实战:求各位数字之和 ```java /** * @author WanJl * @version 1.0 * @title Demo05 * @description 课堂练习:求各位数字之和 * @create 2026/7/15 */ public class Demo05 { public static void main(String[] args) { int n = 12345; int sum = 0; // 累加和 while (n != 0) { sum += n % 10; // 获取个位数字,累加到 sum n /= 10; // 去掉个位,缩小10倍 } System.out.println(sum); // 输出:15 } } ``` ### Demo06.java — 嵌套循环:打印矩形星号图案 ```java /** * @author WanJl * @version 1.0 * @title Demo06 * @description 课堂练习:打印4行5列矩形星号 * @create 2026/7/15 */ public class Demo06 { public static void main(String[] args) { for (int i = 0; i < 4; i++) { // 外层:控制行数 for (int j = 0; j < 5; j++) { // 内层:控制每行星号个数 System.out.print("*"); } System.out.println(); // 换行 } } } ``` ### Demo07.java — 嵌套循环:打印空心矩形星号图案 ```java /** * @author WanJl * @version 1.0 * @title Demo07 * @description 课堂练习:打印5行5列空心矩形星号 * @create 2026/7/15 */ public class Demo07 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { // 外层:控制行数 for (int j = 1; j <= 5; j++) { // 内层:控制列数 if (i == 1 || i == 5) { System.out.print("*"); } else { if (j == 1 || j == 5) { System.out.print("*"); } else { System.out.print(" "); } } } System.out.println(); } } } ``` ### Demo08.java — 嵌套循环:打印菱形星号图案 ```java /** * @author WanJl * @version 1.0 * @title Demo08 * @description 课堂练习:打印5行菱形星号图案 * @create 2026/7/15 */ public class Demo08 { public static void main(String[] args) { for (int i = 1; i <= 5; i++) { for (int j = 1; j <= 5; j++) { if (i == 3) { System.out.print("*"); } else { if (i == 1 || i == 5) { if (j == 3) { System.out.print("*"); } else { System.out.print(" "); } } else if (i == 2 || i == 4) { if (j == 1 || j == 5) { System.out.print(" "); } else { System.out.print("*"); } } } } System.out.println(); } } } ``` ### Demo09.java — 数组(Array) ```java /** * @author WanJl * @version 1.0 * @title Demo09 * @description java引用数据类型 * @create 2026/7/15 */ public class Demo09 { public static void main(String[] args) { // ===== 声明数组变量 ===== int[] a; // int类型的数组变量 // ===== 动态初始化 ===== a = new int[10]; System.out.println(a); // 输出数组在堆内存中的地址值 // ===== 直接声明并动态初始化 ===== int[] arr = new int[10]; // ===== 为数组元素赋值 ===== arr[0] = 1; int x = 15; arr[1] = x; // ===== 访问数组元素 ===== System.out.println(arr[0]); // 1 System.out.println(arr[1]); // 15 System.out.println(arr[2]); // 0(默认值) // ===== 使用 for 循环遍历数组 ===== for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } // ===== 静态初始化(完整写法) ===== int[] arr1 = new int[]{1, 3, 5, 7, 9, 6, 2, 4}; // ===== 静态初始化(简写方式,最常用) ===== int[] arr2 = {1, 3, 5, 7, 9, 6, 2, 4}; } } ``` --- ## 七、随堂练习要点 1. **switch 基本语法**:`switch(变量) { case 常量: 代码块; break; ... default: }` 2. **break 的作用**:跳出 switch 结构,防止穿透(fall-through) 3. **传统 switch**:使用 `case 值:` + `break;` 语法 4. **增强 switch(JDK 17+)**:使用 `case 值 ->` 箭头语法,自带 break 5. **多值匹配**:`case "1", "2", "3" ->` 一个 case 匹配多个值 6. **switch 表达式**:switch 可以直接作为表达式返回值,用于赋值 7. **switch 表达式必须写 default**:确保所有可能值都有对应结果 8. **循环结构**:重复执行某段代码,满足条件就继续循环 9. **for 循环**:`for(初始化; 条件; 迭代) { 循环体 }`,先判断后执行 10. **while 循环**:`while(条件) { 循环体; 迭代; }`,先判断后执行 11. **do...while 循环**:`do { 循环体; 迭代; } while(条件);`,先执行后判断,至少执行一次 12. **死循环**:循环条件永远为 true,应避免出现 13. **迭代语句不能忘**:`while` 和 `do...while` 中必须写 `i++`,否则死循环 14. **for vs while**:已知循环次数用 `for`,不确定次数用 `while` 15. **do...while 特点**:无论条件是否满足,循环体至少执行一次 16. **作业-闰年判断**:`year % 4 == 0 && year % 100 != 0 || year % 400 == 0` 17. **作业-三数比大小**:`a > b ? (a > c ? a : c) : (b > c ? b : c)` 18. **作业-水仙花数**:百位 `/100`、十位 `/10%10`、个位 `%10` 19. **作业-计算器**:除法和取模前必须先判断除数是否为 0 20. **作业-数字加密**:取每位 → 加5 → 取余10 → 位置互换 21. **变量交换**:可使用加减法实现不借助第三变量的交换 22. **进制表示**:`0b` 二进制、`0` 八进制、`0x` 十六进制 23. **循环控制语句**:`break` 结束整个循环,`continue` 结束本轮循环,`return` 结束整个方法 24. **`break`**:跳出当前循环体,继续执行循环后面的代码 25. **`continue`**:跳过本轮循环中剩余代码,直接进入下一轮迭代 26. **`return`**:直接结束整个方法,方法内循环后的所有代码都不再执行 27. **浮点精度陷阱**:`0.1 + 0.2` 不等于 `0.3`,浮点数不能直接用 `==` 比较 28. **switch 穿透利用**:多个 case 执行相同代码时,可以利用穿透特性只在最后一个 case 写 `break` 29. **while 实战-统计位数**:不断除以10直到0,除的次数就是位数 30. **while 实战-数字求和**:`n % 10` 取个位,`n / 10` 去掉个位,循环累加 31. **for vs while 选择**:知道次数用 `for`,不知道次数用 `while` 32. **嵌套循环**:循环里面再放一个循环,外层循环执行一轮,内层循环完整执行一次 33. **嵌套循环执行次数**:内层总次数 = 外层次数 × 内层次数 34. **图形打印核心思路**:外层循环控制行数,内层循环控制列数,if 判断决定每个位置输出什么 35. **打印矩形**:所有位置都输出 `*` 36. **打印空心矩形**:首行/末行全 `*`,中间行首列/末列 `*`,其余空格 37. **打印菱形**:根据行号决定每行星号的排列位置 38. **数组**:用来存储多个相同类型数据的容器,是引用数据类型 39. **数组六要素**:连续存储、索引访问、固定长度、同类型、指定类型、索引从0开始 40. **数组 length 属性**:`数组名.length` 获取数组长度,创建后不可改变 41. **动态初始化**:程序员定义长度,计算机赋默认值,如 `new int[10]` 42. **静态初始化**:程序员赋值,计算机算长度,如 `{1,3,5,7,9}` 43. **数组遍历**:使用 `for` 循环配合 `arr.length` 遍历所有元素 44. **索引越界异常**:访问 `0 ~ length-1` 范围外的索引会抛出 `ArrayIndexOutOfBoundsException` --- ## 八、拓展阅读 | 概念 | 说明 | |------|------| | **switch 穿透(fall-through)** | 传统 switch 中,匹配到某个 case 后若不写 break,会继续执行后续所有 case 的代码 | | **箭头 case `->`** | JDK 17+ 引入的增强 switch 语法,自带 break,右侧可以是表达式、代码块或 throw | | **switch 表达式** | switch 作为表达式使用,可以返回一个值,必须穷举所有可能或提供 default | | **循环(Loop)** | 重复执行某段代码的结构,有 for、while、do...while 三种 | | **死循环(Infinite Loop)** | 循环条件永远为 true,程序无法退出的循环,会导致程序卡死 | | **迭代(Iteration)** | 循环体每执行一次称为一次迭代 | | **初始化语句** | 循环开始前执行的语句,在 for 循环中只执行一次 | | **循环条件** | 布尔表达式,true 继续循环,false 退出循环 | | **迭代语句** | 每次循环结束后执行的语句,通常用于改变循环变量 | | **整除 `/` 与取余 `%`** | 常用于数字分解,如获取一个整数的各个位上的数字 | | **变量交换算法** | 不借助第三个变量,通过加减法或异或运算交换两个变量的值 | | **进制前缀** | `0b`(二进制)、`0`(八进制)、`0x`(十六进制) | | **`break`** | 结束整个循环,继续执行循环后的代码 | | **`continue`** | 结束本轮循环,跳过本轮剩余代码,直接进入下一轮 | | **`return`** | 结束当前方法,方法内所有剩余代码都不执行 | | **浮点精度** | IEEE 754 标准导致 `0.1 + 0.2 ≠ 0.3`,避免用 `==` 直接比较浮点数 | | **switch 穿透** | 不写 `break` 时 case 会穿透到下个 case,可利用此特性合并相同逻辑 | | **嵌套循环** | 循环中嵌套循环,外层每轮内层完整执行一次,总次数 = 外层 × 内层 | | **数字拆位** | `n % 10` 取个位,`n / 10` 去掉个位,`while` 循环可逐位取出所有数字 | | **图形打印** | 外层行、内层列、if 判断输出 `*` 或空格,是嵌套循环的经典二维应用 | | **数组(Array)** | 引用数据类型,用于存储多个相同类型元素的容器 | | **动态初始化** | `new int[10]`,程序员指定长度,计算机赋默认值 | | **静态初始化** | `{1,2,3}`,程序员赋值,计算机计算长度 | | **数组遍历** | 使用 `for` + `arr.length` 逐一访问每个元素 | | **length 属性** | 数组的固有属性,表示数组的长度,创建后不可修改 | | **索引越界** | 访问 `0 ~ length-1` 范围外的索引抛出 `ArrayIndexOutOfBoundsException` | | **数组默认值** | int→0、double→0.0、char→''、boolean→false、引用类型→null |