Java 程式語言使用例外來處理錯誤和其他異常事件。
例外是程式執行期間發生、會打斷指令正常流程的事件。 Java 中的例外是明確引發的,而引發例外的動作稱為_拋出例外_。 處理例外的動作則稱為_捕捉例外_。
在 Java 中,所有例外都是Exception類別的子類別,而Exception本身又是Throwable的子類別。
Java 將例外分為兩種:
_受檢例外_是應用程式應該預期並從中恢復的異常狀況。
受檢例外的一個例子是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類別。
如前所述,例外是會打斷指令正常流程的事件,用來處理_異常事件_。 因此,不建議在你的應用程式中使用例外來控制流程。