異常處理是 Java 程式設計中不可或缺的一環,但許多開發者容易陷入「以異常控制流程」的誤區,導致效能低下。本文整理三大核心技巧,幫助你寫出更健壯、高效的異常處理代碼。
許多初學者習慣用 try-catch 來判斷邏輯分支,例如檢查陣列越界或空指標。但每次拋出異常,JVM 都必須建立新的 Throwable 物件、擷取堆疊追蹤資訊(fillInStackTrace())、調整呼叫堆疊,開銷極大。原則:若能用 if/else 判斷的情況,絕不使用異常。 異常僅應用於真正的錯誤情境(如 I/O 失敗、資料庫連線中斷),而非常規流程控制。
建立新異常物件成本高,若在相同錯誤情境下重複拋出,可考慮預先建立單例異常物件並重用。例如:
private static final MyCustomException INSTANCE = new MyCustomException("固定錯誤訊息");
throw INSTANCE;
但需注意:重用異常會導致堆疊追蹤資訊固定為首次建立時的位置,除非呼叫 fillInStackTrace() 更新。適用於「錯誤碼固定、不需詳細堆疊」的場景。
在迴圈內捕捉異常會導致每次疊代都產生物件與堆疊操作。正確做法是將整個迴圈包裹在 try 區塊中,或在迴圈外預先檢查條件:
// 不佳:迴圈內 try-catch
for (int i=0; i<list.size(); i++) {
try { process(list.get(i)); } catch (Exception e) { ... }
}
// 優化:迴圈外 try-catch
try {
for (int i=0; i<list.size(); i++) { process(list.get(i)); }
} catch (Exception e) { ... }
若某次疊代失敗不應中斷整個迴圈,可在迴圈內用 if 判斷替代,或採用「繼續下一筆」的設計模式。
try-catch 範圍,避免在熱點迴圈中重複捕捉掌握這三大技巧,能顯著提升 Java 應用的穩定性與執行效能。