1. 為什麼需要 try-catch?
如你所知,程式設計中錯誤經常發生:除以零、輸入不正確、檔案不存在等。如果不處理這些情況,程式將以錯誤終止(異常中止)。
構造 try-catch 允許「捕捉」例外並避免程式崩潰,從容地處理錯誤。
try-catch 構造的語法
try
{
// 可能會拋出例外的程式碼
}
catch (TipIsklyucheniya imyaPeremennoy)
{
// 用於處理例外的程式碼
}
說明:
- try — 「嘗試執行這段程式碼」。
- catch — 「如果發生指定型別的例外,就在這裡處理」。
它如何運作?
如果在 try 區塊內發生例外,該區塊的執行會立刻中止,控制權轉移到第一個相符的 catch 區塊。若沒有發生例外,則會略過 catch 區塊。
2. 範例:除以零
未處理例外
int a = 10;
int b = 0;
int result = a / b; // 程式會在此處因錯誤而終止!
System.out.println("結果:" + result); // 這一行永遠不會執行
輸出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:3)
使用 try-catch 處理
int a = 10;
int b = 0;
try
{
int result = a / b; // 這裡可能會發生例外
System.out.println("結果:" + result);
}
catch (ArithmeticException e)
{
System.out.println("錯誤:無法除以零!");
}
System.out.println("程式已繼續執行。");
輸出:
錯誤:無法除以零!
程式已繼續執行。
解釋:
- 一旦 Java 遇到除以零,就會「拋出」例外。
- try 被中斷,控制權轉移到 catch。
- 處理完錯誤後,程式會繼續執行。
3. catch 區塊如何運作
在 catch 後的括號中會指定例外型別(例如 ArithmeticException)以及變數名稱(通常是 e)。
在 catch 區塊內可以取得錯誤的詳細資訊:
- e.getMessage() — 簡短的錯誤描述。
- e.printStackTrace() — 詳細資訊(用於偵錯)。
範例:
try
{
int[] arr = new int[2];
int x = arr[10]; // 錯誤:索引不存在
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("錯誤: " + e.getMessage()); // 輸出錯誤訊息
e.printStackTrace(); // 在主控台列印完整錯誤資訊
}
4. 發生例外時的執行流程
如果在 try 區塊中沒有錯誤 — 會略過 catch 區塊。
如果在 try 區塊中發生錯誤 — 執行會在出錯處中斷,並立即轉移到第一個相符的 catch。在 try 中錯誤之後的內容將不會執行!
示意:
try
{
System.out.println("1. try 開始");
int a = 10 / 0; // 錯誤!
System.out.println("2. 除法之後"); // 不會執行
}
catch (ArithmeticException e)
{
System.out.println("3. 在 catch 區塊中");
}
System.out.println("4. try-catch 之後");
輸出:
1. try 開始
3. 在 catch 區塊中
4. try-catch 之後
5. 使用 try-catch 的常見錯誤
錯誤 № 1:過於寬泛的 catch。
如果使用 catch (Exception e),你可能會攔截大量非預期的錯誤,而無法正確處理它們。
解決方案: 只攔截在該位置確實可預期的例外(例如 IOException、SQLException)。
錯誤 № 2:空的 catch。
寫 catch (Exception e) {} 等於把問題隱藏起來。程式可能在其他地方當掉,或出現怪異行為。
解決方案: 至少要記錄錯誤(e.printStackTrace() 或使用 logger)。
錯誤 № 3:以為 try-catch 可以解決所有問題。
如果是程式邏輯錯誤(例如除以零、演算法不正確),任何 try-catch 都幫不上忙。
解決方案: 僅將 try-catch 用於確實可預期的情況,而不是用來掩蓋 bug。
GO TO FULL VERSION