異常或異常情況(狀態)是程式運作期間發生的錯誤。Java 中的所有異常都是物件。因此,它們不僅可以在發生異常情況時自動生成,還可以由開發人員自己創建。異常類的層次結構: 異常分為幾個類,但它們都有一個共同的祖先-類
Throwable
。它的後代是子類Exception
和Error
。異常 ( Exceptions
) 是程式中原則上可解決和可預測的問題的結果。例如,整數除以零。錯誤 ( Errors
) 是更嚴重的問題,Java 規格指出您不應嘗試在自己的程式中處理,因為它們是 JVM 層級的問題。例如,如果虛擬機器可用的記憶體已耗盡,就會發生此類異常。該程式仍然無法為 JVM 提供額外的記憶體。在Java中,所有異常分為三種類型:檢查異常(checked
)和非檢查異常(unchecked
),其中包括錯誤(Errors
)和運行時異常(RuntimeExceptions
類後代Exception
)。受控異常是可以並且應該在程式中處理的錯誤;類別的所有後代Exception
(但不是RuntimeException
)都屬於這種類型。異常處理可以使用運算子完成try…catch
或轉移到程式的外部部分。例如,方法可以傳遞呼叫層次結構中較高層中發生的異常,而無需自行處理。未經檢查的異常不需要處理,但如果您願意,您可以處理類別異常RuntimeException
。讓我們編譯並執行以下程式:
class Main {
public static void main(String[] args) {
int a = 4;
System.out.println(a/0);
}
}
啟動後,控制台上將顯示以下訊息:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:4)
該訊息顯示發生的異常的類別 - ArithmeticException
。這個異常可以這樣處理:
class Main {
public static void main(String[] args) {
int a = 4;
try {
System.out.println(a/0);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
}
}
}
現在,將執行一個區塊,而不是標準錯誤訊息catch
,該區塊的參數是異常對應的類別的物件e(該物件本身可以給任何名稱,如果我們想強制拋出,則需要它)例如,再次出現此異常,以便檢查其他處理程序)。在這種情況下,該區塊try
包含可能發生異常的程式片段。一個try
可以對應多個具有不同異常類別的catch區塊。
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
Scanner sc = new Scanner(System.in);
try {
int a = sc.nextInt();
m[a] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
}
}
}
如果在啟動所提供的程式後,使用者從鍵盤 1 或 2 輸入,則程式將運作而不會產生任何異常。如果使用者輸入0,則會發生類別異常ArithmeticException
,並由第一個區塊處理catch
。如果使用者輸入3,就會發生類別異常ArrayIndexOutOfBoundsException
(陣列越界),由第二個區塊處理catch
。如果使用者輸入非整數,例如3.14,則會發生類別異常InputMismatchException
(輸入類型不匹配),並且將以標準錯誤格式拋出,因為我們沒有以任何方式處理它。但是,您可以為該類別新增處理程序Exception
,因為該類別是所有其他已檢查異常的父類,因此它將捕獲其中的任何異常(包括InputMismatchException
)。
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
int a = 1;
Scanner sc = new Scanner(System.in);
try {
a = sc.nextInt();
m[a-1] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
} catch (Exception e) {
System.out.println("Произошло ещё Howое-то исключение");
}
}
}
由於異常是建立在類別和子類別的層次結構上的,因此您應該先嘗試處理更具體的異常,然後再處理更一般的異常。也就是說,如果我們將第一個(而不是第三個)區塊與類別異常處理一起放置Exception
,除了「發生了其他異常」之外,我們永遠不會看到任何錯誤訊息(所有異常都會立即被該塊捕獲,並且不會到達其餘的部分)。區塊的可選添加try…catch
可以是區塊finally
。放置在其中的命令在任何情況下都會被執行,無論是否發生異常。儘管事實上,當發生未處理的異常時,該異常產生後剩餘的程式部分不會被執行。例如,如果在某些冗長的計算過程中發生異常,finally
您可以在區塊中顯示或儲存中間結果。連結至來源:異常及其處理
GO TO FULL VERSION