Java基礎系列文章
Java基礎(一):發展史、技術體系與JDK環境配置詳解
Java基礎(二):八種基本數據類型詳解
Java基礎(三):邏輯運算符詳解
Java基礎(四):位運算符詳解
Java基礎(五):if/switch與for/while - 深入理解流程控制
目錄
- 引言
- 一、分支結構
- 1、if語句
- 2、if-else語句
- 3、if-else-if階梯
- 4、switch語句 (傳統與現代)
- 4.1、傳統語法 (Java 7 及之前,注意break)
- 4.2、現代語法 (Java 12+, 使用->箭頭和yield)
- 4.3、更高級語法 (Java 17+, 模式匹配預覽特性)
- 二、循環結構
- 1、for循環
- 2、while循環
- 3、do-while循環
- 4、增強for循環 (for-each)
- 三、流程控制的利器:break和continue
- 1、break語句
- 2、continue語句
- 3、帶標簽的break和continue(謹慎使用)
- 四、無限循環與空語句
- 1、無限循環
- 2、空語句
- 總結
引言
??流程控制
是編程語言的基石,它決定了代碼執行的順序
和路徑
。Java提供了強大而靈活的流程控制語句,使你能夠根據條件執行代碼、重復執行任務以及跳出循環。掌握這些結構是寫出高效、邏輯清晰程序的關鍵。
一、分支結構
1、if語句
- 語法:
if (condition) {// 當 condition 為 true 時執行的代碼塊 }
- 執行流程:
- 計算
condition
(必須是一個布爾表達式:true
或false
) - 如果結果為
true
,則執行代碼塊內的語句 - 如果結果為
false
,則跳過代碼塊,繼續執行后面的代碼
- 計算
- 示例:
int age = 18; if (age >= 18) {System.out.println("你已成年。"); } // 無論 age 是否 >=18, 這行都會執行 System.out.println("年齡檢查完畢。");
2、if-else語句
- 語法:
if (condition) {// 當 condition 為 true 時執行的代碼塊 } else {// 當 condition 為 false 時執行的代碼塊 }
- 執行流程:
- 計算
condition
- 如果
true
,執行if
代碼塊 - 如果
false
,執行else
代碼塊 - 兩個代碼塊
必選其一
執行,且只執行其一
- 計算
- 示例:
int score = 75; if (score >= 60) {System.out.println("及格!"); } else {System.out.println("不及格!"); }
3、if-else-if階梯
- 語法:
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
,則整個結構不執行任何操作
- 按順序檢查每個
- 示例:
int grade = 85; if (grade >= 90) {System.out.println("優秀 (A)"); } else if (grade >= 80) { // 隱含 grade < 90System.out.println("良好 (B)"); } else if (grade >= 70) { // 隱含 grade < 80System.out.println("中等 (C)"); } else if (grade >= 60) { // 隱含 grade < 70System.out.println("及格 (D)"); } else {System.out.println("不及格 (F)"); }
4、switch語句 (傳統與現代)
??基于一個表達式
的值,從多個可能的執行路徑中選擇一個。適用于多分支選擇,尤其當分支基于單個變量或表達式的離散值(整數、字符、字符串 String
、枚舉 enum
)時,通常比 if-else-if
更清晰。
4.1、傳統語法 (Java 7 及之前,注意break)
switch (expression) {case value1:// expression 等于 value1 時執行的語句break; // 跳出 switch 塊case value2:// expression 等于 value2 時執行的語句break;... // 可以有任意多個 casedefault:// 如果 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):
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 穿透):
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
語句,無穿透):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 或 5default -> System.out.println("周末或無效日期"); } // 輸出: 星期三 \n 一周的中點!
-
示例 (
switch
表達式,使用yield
返回值,類似于return
):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 分支中直接進行類型判斷
和綁定變量
,從而讓代碼更簡潔、更安全。
static String test(Object obj) {return switch (obj) {case String s -> "字符串: " + s;case Integer i -> "整數: " + i;case null -> "空值";default -> "其他類型";};
}
- case String s -> …:如果 obj 是一個字符串,就匹配并將其綁定到變量 s
- case Integer i -> …:同理,匹配整數
- case null -> …:甚至可以對 null 值進行單獨處理
- default -> …:兜底處理其他類型
注意??:這是預覽功能:意味著它還不是 Java 標準的一部分,將來可能會改動,從 Java 21 開始,這一功能有望正式成為標準
二、循環結構
1、for循環
- 用途:當
循環次數已知
或在循環前就知道初始化、條件和迭代步驟
時特別適用。結構清晰 - 傳統語法:
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
,循環終止
- 執行
- 示例:
// 打印 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);
- 格式的多樣性(
多變量控制
、省略部分語句
)// 省略部分語句(但必須保留分號) 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循環
- 用途:當
循環次數未知
,但在循環開始前有一個明確的繼續條件
時適用。先判斷條件,再決定是否執行循環體 - 語法:
while (condition) {// 循環體:當 condition 為 true 時重復執行的代碼 }
- 執行流程:
- 計算
condition
- 如果
condition
為true
:- 執行循環體
- 回到步驟 1 (再次檢查
condition
)
- 如果
condition
為false
,循環終止
- 計算
- 特點:循環體可能
一次都不執行
(如果初始條件就是false
) - 示例:
int i = 0; while (i < 5) {System.out.println(i);i++; }
3、do-while循環
- 用途:當
循環體至少需要執行一次
,然后再根據條件決定是否繼續時適用。先執行一次循環體,再判斷條件 - 語法:
do {// 循環體:至少執行一次 } while (condition); // 注意結尾的分號
- 執行流程:
- 執行循環體
- 計算
condition
- 如果
condition
為true
,回到步驟 1 - 如果
condition
為false
,循環終止
- 特點:循環體
至少執行一次
- 示例:
// 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
)。語法簡潔,避免了顯式索引操作 - 語法:
for (ElementType element : collectionOrArray) {// 使用 element 執行操作 }
ElementType
:集合或數組中元素的類型
element
:循環變量
,在每次迭代中依次被賦值為集合或數組中的當前元素collectionOrArray
:要遍歷的數組
或集合
對象
- 執行流程:自動依次從數組或集合中取出每個元素,賦值給
element
,并執行循環體。遍歷完所有元素后結束 優點
:簡潔、安全(無需管理索引)、不易出錯(避免索引越界)缺點
:不能直接訪問當前元素的索引;不能修改集合結構(如刪除元素,否則可能引發ConcurrentModificationException
);只能單向順序遍歷- 示例:
// 1.遍歷數組 int[] numbers = {1, 2, 3, 4, 5}; for (int num : numbers) {System.out.print(num + " "); } // 輸出: 1 2 3 4 5// 2.遍歷 List 集合 List<String> fruits = Arrays.asList("Apple", "Banana", "Orange"); for (String fruit : fruits) {System.out.println(fruit); } // 輸出: Apple \n Banana \n Orange
三、流程控制的利器:break和continue
1、break語句
- 用途:
- 在循環中 (
for
,while
,do-while
):立即終止
其所在的最內層循環,跳出循環體,繼續執行循環之后的代碼 - 在
switch
中:終止case
的執行并跳出整個switch
塊(防止穿透)
- 在循環中 (
- 示例 (跳出循環):
// 查找數組中第一個負數 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
語句之后
的所有代碼,立即進入下一次迭代
(檢查循環條件并執行步進語句) - 示例:
// 打印 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 9
3、帶標簽的break和continue(謹慎使用)
- 用途:用于跳出
多層嵌套
的循環或語句塊 - 語法:在目標循環或語句塊
前
放置一個標簽 (label:
), 然后在break
或continue
后指定該標簽名 (break label;
/continue label;
) break label;
:立即終止標簽所標記的整個
循環或語句塊-
continue label;
:立即跳轉到標簽所標記的循環的下一次迭代
開始處(跳過標記循環當前迭代的剩余部分) - 示例 (跳出外層循環):
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
的循環,理論上會一直執行下去 - 常見形式:
// while 形式 while (true) {// ... 需要某種 break 條件跳出 ... } // for 形式 for (;;) { // 初始化、條件、迭代都省略// ... 需要某種 break 條件跳出 ... }
- 用途:服務器監聽、游戲主循環、需要用戶主動退出的程序等。必須在循環體內提供跳出機制(如
break
,return
,System.exit()
) - 風險:如果缺少跳出機制,程序將永遠掛起,消耗CPU資源
2、空語句
- 定義:一個單獨的分號
;
表示一條不執行任何操作的語句 - 在流程控制中的潛在陷阱:
// 意圖: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程序的基礎。