軌道
/
Java
Java
/
課程大綱
/
例外狀況
例外

例外狀況 在 Java

25 個練習

關於 例外狀況

Java 程式語言使用例外來處理錯誤和其他異常事件。

什麼是例外

例外是程式執行期間發生、會打斷指令正常流程的事件。 Java 中的例外是明確引發的,而引發例外的動作稱為_拋出例外_。 處理例外的動作則稱為_捕捉例外_。

在 Java 中,所有例外都是Exception類別的子類別,而Exception本身又是Throwable的子類別。

Java 將例外分為兩種:

  1. 受檢例外
  2. 未受檢例外

受檢例外

_受檢例外_是應用程式應該預期並從中恢復的異常狀況。 受檢例外的一個例子是FileNotFoundException,當方法嘗試讀取不存在的檔案時就會發生。

這類例外會在編譯期檢查:會拋出受檢例外的方法,應該在方法簽章中註明這一點,而呼叫可能拋出受檢例外的方法的程式碼,必須處理它,否則無法編譯。

所有受檢例外都是Exception的子類別,且未繼承RuntimeException。

未受檢例外

_未受檢例外_是應用程式通常無法預期或從中恢復的異常狀況。 未受檢例外的一個例子是NullPointerException,當方法期待非 null 的值卻收到null時就會發生。

這類例外不會在編譯期檢查:會拋出未受檢例外的方法,不需要在方法簽章中註明,而呼叫可能拋出未受檢例外的方法的程式碼,也不需要處理它。

所有未受檢例外都繼承自RuntimeException,而RuntimeException本身又是Exception的延伸。

拋出例外

Java 中的方法可以使用 throw敘述拋出例外。

拋出受檢例外

從方法拋出受檢例外時,必須使用 throws關鍵字在方法簽章中註明,如下方範例所示。 這會強制呼叫端的程式碼預期可能拋出例外,並據此處理。

public class InsufficientBalanceException extends Exception {

}

public class BankAccount {
  public void withdraw(double amount) throws InsufficientBalanceException {
    if (balance < amount) {
      throw new InsufficientBalanceException();
    }

    // rest of the method implementation
  }
}

拋出未受檢例外

從方法拋出未受檢例外時,不需要在方法簽章中註明,不過 Java 支援這麼做。

public class BankAccount {
  public void withdraw(double amount) {
    if (amount < 0) {
      throw new IllegalArgumentException("Cannot withdraw a negative amount");
    }

    // rest of the method implementation
  }
}

處理例外

在 Java 中處理例外,是透過 try、catch 和 finally 關鍵字完成的。

  • 可能拋出例外的程式碼敘述應該包在try區塊中。
  • try區塊後面接著一個或多個catch區塊,用來捕捉try區塊中拋出的例外。
  • catch區塊後面可以選擇性地接著finally區塊,無論是否拋出例外,它都會在try區塊之後執行。

下面的範例說明這些關鍵字的運作方式:

public class ATM {
  public void withdraw(BankAccount bankAccount, double amount) {
    try {
      System.out.println("Withdrawing " + amount);
      bankAccount.withdraw(amount);
      System.out.println("Withdrawal succeeded");
    } catch (InsufficientBalanceException) {
      System.out.println("Withdrawal failed: insufficient balance");
    } catch (RuntimeException e) {
      System.out.println("Withdrawal failed: " + e.getMessage());
    } finally {
      System.out.println("Current balance: " + bankAccount.getBalance());
    }
  }
}

在這個範例中,沒有拋出例外時,會印出:

Withdrawing 10.0
Withdrawal succeeded
Current balance: 5.0

不過,如果bankAccount.withdraw(amount)敘述拋出InsufficientBalanceException,則會印出:

Withdrawing 10.0
Withdrawal failed: insufficient balance
Current balance: 5.0

或者,如果bankAccount.withdraw(amount)拋出的是未受檢例外,則會印出:

Withdrawing -10.0
Withdrawal failed: Cannot withdraw a negative amount
Current balance: 5.0

錯誤

Java 另外有一個獨立的類別叫做_錯誤_,指的是應用程式外部的嚴重問題。 錯誤的一個例子是OutOfMemoryError,當應用程式嘗試使用的記憶體超過系統可用記憶體時就會發生。

和未受檢例外一樣,錯誤不會在編譯期檢查。 差別在於,它們代表系統層級的問題,通常由 Java 虛擬機器或環境拋出,而不是應用程式。 應用程式一般不應該嘗試捕捉或處理它們。

Java 中所有錯誤都繼承自Error類別。

什麼時候不該使用例外

如前所述,例外是會打斷指令正常流程的事件,用來處理_異常事件_。 因此,不建議在你的應用程式中使用例外來控制流程。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 例外狀況