如圖可以看出所有的異常跟錯誤都繼承與Throwable類,也就是說所有的異常都是一個對象。
從大體來分異常為兩塊:
1、error---錯誤 : 是指程序無法處理的錯誤,表示應用程序運行時出現的重大錯誤。例如jvm運行時出現的OutOfMemoryError以及Socket編程時出現的端口占用等程序無法處理的錯誤。
2、Exception --- 異常 :異常可分為運行時異常跟編譯異常
?1)運行時異常:即RuntimeException及其之類的異常。這類異常在代碼編寫的時候不會被編譯器所檢測出來,是可以不需要被捕獲,但是程序員也可以根據需要進行捕獲拋出。常見的RUNtimeException有:NullpointException(空指針異常),ClassCastException(類型轉換異常),IndexOutOfBoundsException(數組越界異常)等。
?2)編譯異常:RuntimeException以外的異常。這類異常在編譯時編譯器會提示需要捕獲,如果不進行捕獲則編譯錯誤。常見編譯異常有:IOException(流傳輸異常),SQLException(數據庫操作異常)等。
3、java處理異常的機制:拋出異常以及捕獲異常 ,一個方法所能捕捉的異常,一定是Java代碼在某處所拋出的異常。簡單地說,異常總是先被拋出,后被捕捉的。
4、throw跟throws的區別:
public void test() throws Exception {? ? throw new Exception();}
從上面這一段代碼可以明顯的看出兩者的區別。throws表示一個方法聲明可能拋出一個異常,throw表示此處拋出一個已定義的異常(可以是自定義需繼承Exception,也可以是java自己給出的異常類)。
5、接下來看一下如何捕獲異常:
1)首先java對于異常捕獲使用的是try---catch或try --- catch --- finally 代碼塊,程序會捕獲try代碼塊里面的代碼,若捕獲到異常則進行catch代碼塊處理。若有finally則在catch處理后執行finally里面的代碼。然而存在這樣兩個問題:
a.看如下代碼:
try{? ?
?//待捕獲代碼
}
catch(Exception e){? ??
System.out.println("catch is begin");? ??
return 1 ;
}finally{? ?
?System.out.println("finally is begin");
}
在catch里面有一個return,那么finally會不會被執行呢?答案是肯定的,上面代碼的執行結果為:
catch is beginfinally is begin?
也就是說會先執行catch里面的代碼后執行finally里面的代碼最后才return1 ;
b.看如下代碼:
try{?
?//待捕獲代碼? ?
?}catch(Exception e){??
? System.out.println("catch is begin");? ?
?return 1 ;
}finally{? ??
?System.out.println("finally is begin");? ?
?return 2 ;
}
在b代碼中輸出結果跟a是一樣的,然而返回的是return 2 ; 原因很明顯,就是執行了finally后已經return了,所以catch里面的return不會被執行到。也就是說finally永遠都會在catch的return前被執行。(這個是面試經常問到的問題哦!)
6、對于異常的捕獲不應該覺得方便而將幾個異常合成一個Exception進行捕獲,比如有IO的異常跟SQL的異常,這樣完全不同的兩個異常應該分開處理!而且在catch里處理異常的時候不要簡單的e.printStackTrace(),而是應該進行詳細的處理。比如進行console打印詳情或者進行日志記錄。
注意:異常和錯誤的區別:異常能被程序本身可以處理,錯誤是無法處理。