本文依據 Java 語言規範與主流認證大綱,系統整理流程控制(if/switch/loop)與異常處理(try/catch/finally/throws)的語法規則、邊界行為、常見陷阱與最佳實踐。
| 迴圈 | 判斷時機 | 至少執行一次 | 適用場景 |
| while | 迴圈前 | 否 | 次數未知、前置條件 |
| do-while | 迴圈後 | 是 | 選單、輸入驗證 |
| for | 迴圈前 | 否 | 計數、範圍迭代 |
for 進階語法
- 初始化區:可宣告多個同型別變數(逗號分隔),或多個陳述式,但不可混合宣告與陳述式
- 迭代區:多個陳述式逗號分隔,全部執行(無短路)
- 增強 for(for-each):
for (Type var : array/Iterable),唯讀遍歷,無索引
4. break / continue / 標籤
break:跳出最內層 switch/迴圈/標籤區塊
continue:跳過本次迴圈剩餘部分,直接進入下一次迭代判斷(僅用於迴圈)
- 標籤:
label: statement,命名規則同識別字;可用於非迴圈區塊(配合 break)
- 標籤名可重複,只要不巢狀包含;可與套件/類別/方法/變數同名
- 標籤實際上可套用於任意陳述式,但僅在 break/continue 語境有意義
5. Unreachable Code(不可到達程式碼)
while(false){}、for(;false;){} → 編譯錯誤
if(false){} → 合法(保留條件編譯彈性)
while(1==2){} → 合法(編譯器不做常數摺疊判斷)
二、異常處理機制
1. 異常體系
Throwable
├── Error(系統級嚴重錯誤,不可恢復,如 OutOfMemoryError)
└── Exception
├── RuntimeException(非受檢,編譯器不強制處理)
│ ├── NullPointerException
│ ├── IllegalArgumentException
│ ├── IndexOutOfBoundsException (→ ArrayIndexOutOfBoundsException, StringIndexOutOfBoundsException)
│ ├── ArithmeticException
│ ├── ClassCastException
│ └── SecurityException
└── 受檢異常(Checked Exception,必須 catch 或 throws)
├── IOException (→ FileNotFoundException, EOFException, SocketException, MalformedURLException...)
├── ClassNotFoundException
├── InterruptedException
├── SQLException
└── 自訂受檢異常
2. 處理規則:Catch or Declare
- 方法/建構子內拋出受檢異常 → 必須
try-catch 處理 或 在簽名加 throws ExceptionType
RuntimeException、Error 及其子類:無須 處理或宣告
- 可兩者皆做(catch 後再 throws),編譯器不報錯
3. throw 語句
throw new MyException("msg");
- 若丟擲
null → 實際拋出 NullPointerException
4. 呼叫鏈傳遞
- A() 宣告
throws X → B() 呼叫 A() → B() 必須 catch X 或 throws X
5. try-catch-finally 執行語義
- try 區塊拋出異常 → 立即跳出 try,進入匹配的 catch(子類優先)
- 若 try 區塊呼叫方法拋出異常 → 該方法即刻中止,回到呼叫點
- catch 區塊處理完 → 異常視為已處理,繼續執行 finally(若有)
- 捕獲順序:必須從子類到父類(否則父類攔截導致子類不可達,編譯錯誤)
- 至少一個 catch 或 finally 必須存在;三者並存順序固定:
try-catch-finally
finally 必定執行(正常返回、拋出異常、catch 返回、catch 拋出新異常),例外:System.exit()、JVM 崩潰、無限迴圈、執行緒被 stop() 強制終止
- 若無異常或已處理 → 執行完 finally 後繼續後續程式碼
- 若未處理 → 向上傳遞至呼叫端 try,最終達執行緒頂層 → 執行緒終止、堆疊輸出至
System.err
6. catch 區塊再拋出
catch (X e) { throw e; } 或包裝 throw new Y(e);
- 再拋出的異常不被同層其他 catch 捕獲,需外層 try 或方法簽名
throws
7. 覆寫方法與異常
- 覆寫方法不得拋出比父類更寬泛的受檢異常(可拋出子類、或不拋出、或拋出非受檢異常)
- 父類無 throws → 子類不可加受檢 throws
8. 編譯器檢查細節
- try 區塊無拋出對應受檢異常的程式碼 → 對應 catch 會報錯(
Exception 等超類除外)
三、高頻陷阱題範例
// 1. switch 型別檢查
byte b = 10;
switch(b) { case 200: } // 編譯錯誤:200 超出 byte 範圍
// 2. for 初始化區混合宣告
for (int i = 0, j = 0; i < 10; i++, j++) {} // 合法
for (int i = 0, double d = 0.0; i < 10; i++) {} // 編譯錯誤:型別混合
// 3. finally 返回值覆蓋
try { return 1; } finally { return 2; } // 方法返回 2
// 4. 覆寫異常限制
class Parent { void m() throws IOException {} }
class Child extends Parent { void m() throws Exception {} } // 編譯錯誤:Exception 比 IOException 寬
// 5. catch 子類先於父類
try {} catch (Exception e) {} catch (IOException e) {} // 編譯錯誤:IOException 永不被捕獲
結語
流程控制與異常處理是 Java 程式健壯性的基石。精通 switch 型別規則、for 初始化區限制、finally 執行保證、受檢/非受檢異常分野、覆寫時的異常收斂規則,不僅能通過認證考試,更能寫出正確、可維護、可診斷的生產級代碼。
- 上一篇文章: Java 代碼保護實戰:反編譯工具鏈與擾碼器(Obfuscator)深度對比
- 下一篇文章: Servlet + JDBC 實戰:資料庫記錄的顯示、新增與更新完整教學
Copyright ©
程式碼之家 All Rights Reserved