早期語言(如 C)缺乏例外處理,靠回傳特殊值或旗標判斷錯誤,隨系統規模擴大成為大型可維護程式障礙。Java 在 C++ 基礎上建立完善例外機制,採物件導向分類各類例外並提供良好介面,為複雜程式提供強力控制,同時將例外程式碼與常規程式碼分離,增強可讀性與編寫彈性。另一優勢:無法確定處理時可拋出上層,錯誤處理更有條理易維護。
所有例外皆為物件,屬 Throwable 或其子類別實例。方法拋出例外物件攜帶錯誤資訊,呼叫端捕獲處理。Throwable 兩大標準子類:
編譯器檢查:非執行期例外(如 FileNotFoundException、IOException)必須捕獲或宣告拋出;執行期例外(RuntimeException 及子類)可不處理,因普遍且全捕獲影響可讀性與效能。
try、catch、throw、throws、finally。基本架構:
try {
// 可能拋出例外的程式區塊
} catch (ExceptionType1 e) {
// 處理 ExceptionType1
} catch (ExceptionType2 e) {
// 處理 ExceptionType2
} finally {
// 無論是否發生例外皆執行
}
try 區塊建立例外框架於堆疊,執行完畢才移除。若內層 try 未處理某例外,堆疊展開尋找外層處理者。catch 子句指定欲捕獲的例外類型。
throw:明確拋出例外實例(throw new IllegalAccessException("demo")),流程立即停止throws:宣告方法可能拋出的例外類別,編譯器強制檢查非執行期例外確保程式碼無論發生何事(正常返回、未捕獲例外、明確 return)皆在方法返回前執行。return 實際在 finally 執行完後才生效。
class ExceptionDemo {
static void procA() {
try {
System.out.println("inside procA");
throw new RuntimeException("demo");
} finally {
System.out.println("procA's finally"); // 任何情況都會執行
}
}
static void procB() {
try {
System.out.println("inside procB");
return; // 實際在 finally 後才返回
} finally {
System.out.println("procB's finally");
}
}
public static void main(String[] args) {
try {
procA();
} catch (Exception e) {
System.out.println("catch: " + e);
}
procB();
}
}
大量練習修改範例程式,是掌握流程控制與例外處理的最佳途徑。