當一個程序出現錯誤時,可能是以下三種錯誤:
- 語法錯誤:如缺少必要的標點符號、關鍵字輸入錯誤、數據類型不匹配等,在編譯器對程序進行編譯的過程中,會把檢測到的語法錯誤以提示的方式列舉出來,故又稱爲編譯錯誤。
- 運行時錯誤:如空指針異常,數組越界,除數爲零、數據庫連接失敗等,迫使程序終止,有特定的發生條件。
- 邏輯錯誤:在語法上是有效的,但是在邏輯上是錯誤的,此類問題不好調試。
這裏說的Java異常處理機制主要是指處理運行時錯誤。
a.Throwable繼承層次結構,可見分成兩大類Error和Exception。
Error
(錯誤):指程序無法恢復的異常情況,表示運行應用程序中較嚴重的問題。- 發生於虛擬機自身、或者在虛擬機試圖執行應用時,如
Virtual MachineError
(Java虛擬機運行錯誤)、NoClassDefFoundError
(類定義錯誤)。 - 屬於不可查異常,即不強制程序員必須處理,即使不處理也不會出現語法錯誤。
- 發生於虛擬機自身、或者在虛擬機試圖執行應用時,如
Exception
(異常):指程序有可能恢復的異常情況,表示程序本身可以處理的異常。又分兩大類:RuntimeException
(運行時異常):由程序自身的問題導致產生的異常。- 如
NullPointerException
(空指針異常)、IndexOutOfBoundsException
(下標越界異常)。 - 屬於不可查異常。
- 如
- 非運行時異常:由程序外部的問題引起的異常。
- 除了RuntimeException以外的異常,如
FileNotFoundException
(文件不存在異常)。 - 屬於可查異常,即強制程序員必須進行處理,如果不進行處理則會出現語法錯誤。
- 除了RuntimeException以外的異常,如
附:常見的異常及其含義如圖
b.異常處理機制
(1)捕捉異常:由系統自動拋出異常
try
捕獲異常:用於監控,若發生異常,會拋出異常類所產生的對象並立刻結束執行,並轉向異常處理catch塊。catch
處理異常:若拋出的異常對象屬於catch內所定義的異常類,則進入catch中的對應代碼段繼續運行程序,反之進入finally塊。常用方法:e.getMessage()
:返回異常對象的一個簡短描述e.toString()
:獲取異常對象的詳細信息e.printStackTrace()
:在控制檯上打印異常對象和它的追蹤信息
finally
最終處理:無論是否捕獲或處理異常,finally塊裏的語句都會被執行。在以下4種特殊情況下,finally塊纔不會被執行:- 在finally語句塊中發生了異常
- 在前面的代碼中用了
System.exit()
退出程序 - 程序所在的線程死亡
- 關閉CPU
try {
// 可能會發生異常的程序代碼
} catch (異常類1 異常變量) {
// 捕獲並處理try拋出的異常類型Type1
} catch (異常類2 異常變量) {
// 捕獲並處理try拋出的異常類型Type2
} finally {
// 無論是否發生異常,都將執行的語句塊
}
注意:
- 一個try、catch、finally之間不能插入其它代碼
- catch可有多個,try和finally只能有一個
- try後面必須至少跟着catch和finally其中的一個
(2)拋出異常:在方法中將異常對象顯性地拋出,之後異常會沿着調用層次向上拋出,交由調用它的方法來處理。
throws
:聲明拋出的異常,位置在方法名後、異常類型前throw
:拋出異常,一般在方法體內部
(3)自定義異常:繼承Execption類或其子類,實現步驟如下:
- 聲明自定義異常類並繼承Exception,可重寫方法如
getMessage()
- 在方法頭用
throws
聲明該方法可能拋出的異常 - 在方法體的適當位置創建自定義異常類對象,並用
throw
將異常拋出 - 調用該方法時,對可能產生的異常進行捕獲,並處理異常
//1.自定義的異常類
class MyException extends Exception {
String message;
public MyException(String ErrorMessagr) {
super(ErrorMessagr) ;
}
public String getMessage() {
return message;
}
}
public class Demo {
public static void main(String[] args) {
//4.調用方法時捕獲和處理
try {
test();
} catch (MyException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
//2.在方法頭聲明可能出現的異常
public static void test() throws MyException{
try {
int i = 10/0;
System.out.println("i="+i);
} catch (ArithmeticException e) {
//3.在適當情況下拋出異常
throw new MyException("This is MyException");
}
}
}