無論我們走到哪裡,不可預測的事件都在等著我們。地震、人們的非理性行為、隕石……或更簡單的事——燈泡燒壞、銀行卡消磁、汽油表壞了。我們無法阻止不可預測的事件發生,但我們至少可以為它們做好部分準備。也就是說,我們必須準備一定的機制來應對。在程式設計領域,特別是在Java語言中,阻止程式正常運作的事件稱為異常,而防止程式崩潰的機制稱為異常處理。因此,當程式中發生意外事件(例如除以零)時,它應該「拋出」異常。異常處理是Java程式設計的一個重要方面,它可以幫助開發人員管理程式執行期間可能發生的錯誤和異常。在本文中,我們將重點討論異常處理的基本概念之一:Java throw關鍵字以及如何使用它來引發異常。
Java 中的異常是什麼?
異常是在程式執行期間發生的破壞程序指令正常流程的事件。當發生異常時,程式執行會停止,並在控制台上顯示錯誤訊息。在Java中,有兩種類型的異常:受控異常和非受控異常。檢查異常在編譯時進行檢查,編譯器確保它們被呼叫方法捕獲或聲明。另一方面,未檢查的異常在編譯時不會被檢查,並且它們可以被捕獲或不被捕獲。下面是一個可能發生錯誤但編譯器會跳過它的程式碼範例。
public class Factorial {
public static long getFactorial(final int number) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
這是程式的輸出:
1 -4249290049419214848
程序正確退出,但產生了錯誤的結果。在第一種情況下,因為函數參數為負數,且階乘不適用於負數。在第二種情況下,結果是錯誤的,因為數字太大,無法在 long 類型的範圍內計算其階乘。這是另一個例子。讓我們寫一個程序,將一個數字除以另一個數字。
public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
int result = divide(a, b);
System.out.println(result);
}
public static int divide(int a, int b) {
return a / b;
}
}
在此範例中,由於變數 b 為零,因此將引發ArithmeticException 。但是,此錯誤未處理,因此程式會以錯誤狀態退出。
Java中如何拋出例外
在Java中,異常也是對象,因此拋出異常就像創建一個新的Exception對像一樣。程式中使用 throw 語句拋出異常。通常,這兩個操作(物件建立和拋出異常)合併為一個:
throw new Exception("error…");
Java 中的throw 關鍵字用於當發生程式在執行時無法處理的錯誤或異常情況時,從方法或程式碼區塊中拋出異常。程式流程被重定向到最近的 catch 區塊。該區塊可以管理異常。
“throw”關鍵字用法範例
為了說明 Java 中throw關鍵字的功能,我們舉一個例子。讓我們寫一個方法來計算數字的階乘。如果數字為負數,則無法計算,因此必須拋出異常。同樣,如果數字太大,階乘結果將超過 long 類型的最大大小,並且將引發另一個異常。這裡我們有該方法的實作:
public Class Factorial {
public static long getFactorial(final int number) {
if ((number >= 0) && (number < 21)) {
long fact = 1;
for (int i = 1; i <= number; i++) {
fact = fact * i;
}
return fact;
} else {
//throw new exception here
throw new IllegalArgumentException("THe argument isn't legal");
}
}
public static void main(String[] args) {
System.out.println(getFactorial(-5));
System.out.println(getFactorial(21));
}
}
在此範例中,如果number 的值為負數,則使用throw關鍵字拋出IllegalArgumentException類別的實例。如果運行該程序,控制台上將顯示「參數不合法」訊息。程序執行將被停止。
不再有錯誤:捕獲異常範例
現在讓我們回憶一下第二個例子,除以零,並透過異常處理來執行它。
public class DivisionExample {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
int result = divide(a, b);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Error: division by zero");
}
}
public static int divide(int a, int b) {
return a / b;
}
}
在此範例中,我們新增了一個try-catch構造來處理被零除異常。簡而言之,try-catch-finally是一種 Java 程式語言結構,它允許您處理異常並執行程式碼,無論是否發生異常。 try-catch-finally由三個區塊組成:
- try塊。這裡正在執行潛在危險的程式碼。那是可以拋出異常的程式碼。如果try區塊內發生異常,則中止該區塊中程式碼的執行,並將控制權轉移到 catch 區塊。
- 捕獲塊。這裡處理拋出的例外。在catch區塊中,您可以指定要擷取哪個例外狀況以及擷取時執行什麼邏輯。 最後的塊。無論是否發生異常,都會執行此操作。例如,finally區塊用於釋放在 try 區塊中指派的資源(例如關閉檔案或套接字)。您可以省略此區塊。
拋出關鍵字
throws關鍵字用在方法簽章。如果是這樣,則表示該方法中拋出了異常。這可以將異常傳播到呼叫堆疊並指示不需要在目前方法中處理異常。在 Java 中,「拋出」也可用於指稱程式中定義的自訂例外狀況。 例如,一個方法可以執行兩個數字的除法,但如果第二個參數為零, 則拋出IllegalArgumentException :
public static double divide(double a, double b) throws IllegalArgumentException {
if (b == 0) {
throw new IllegalArgumentException("Division by zero is not allowed");
}
return a / b;
}
此方法使用 throws 關鍵字來指示如果第二個參數為 null,則可以拋出IllegalArgumentException 。如果在執行該方法時發生此類異常,則會將其傳遞給呼叫方法進行處理。方法呼叫範例:
public static void main(String[] args) {
double result = 0;
try {
result = divide(10, 0);
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("Result: " + result);
}
在此範例中,使用參數 10 和 0 呼叫divide()方法,由於不可能除以零,因此將拋出IllegalArgumentException 。異常將被try-catch區塊捕獲,並顯示錯誤訊息。由於異常終止了divide()方法的執行,因此程式將導致值為零。