先上圖
Java中所有的異常類都是繼承于
Throwable
的,表示可以拋出的對象筋蓖。Error
(錯誤):是程序無法處理的錯誤粘咖,表示運行應用程序中較嚴重問題。大多數(shù)錯誤與代碼編寫者執(zhí)行的操作無關涂炎,而表示代碼運行時 JVM(Java 虛擬機)出現(xiàn)的問題。比如:內(nèi)存溢出什么的。Exception
(異常):與Error
不同震缭,表示程序可以處理的錯誤拣宰。RuntimeException
:雖然寫的是運行時異常烦感,但是這里面提到的全部異常都是運行時發(fā)生了,這個名字其實不是很好晌该。RuntimeException
表示的是程序邏輯出現(xiàn)錯誤朝群,導致的。IOException
:指一些IO
方面的異常姜胖?(感覺也不是很準確)
需要注意的是
Error
和RuntimeException
都是未檢查異常右莱,也就是說不需要使用try...catch
來進行捕獲档插。但是IOException
屬于檢查型異常是必須使用try...catch
來進行捕獲或者將其拋出到外層調(diào)用者函數(shù)。
舉個栗子
public class TTestException {
public void a() throws MyException {
throw new MyException();
}
public void b(){
try {
throw new MyException();
} catch (MyException e) {
e.printStackTrace();
}
}
public void c(){
String s = null;
System.out.println(s.length());
}
public static void main(String[] args) {
TTestException tTestException = new TTestException();
try {
tTestException.a();
} catch (MyException e) {
e.printStackTrace();
}
tTestException.b();
System.out.println("After b() before c()");
tTestException.c();
System.out.println("After c()");
}
}
這個例子里面a
和b
都會拋出檢查型異常胀瞪,但是a
是把異常再次向調(diào)用者拋出凄诞,b
是直接在函數(shù)內(nèi)部就進行處理了帆谍。
再觀察外層調(diào)用會拋出檢查型異常的情況轴咱,調(diào)用a
的時候是必須對其進行處理的,要不就是try...catch
或者就是再次向外拋出窖剑,這里就應該明白一個道理就是一個檢查型異常是必須在程序的某個層次中進行處理的,既然程序中進行了處理讶舰,那么這個檢查型異常是不會導致程序停止的
,調(diào)用b
函數(shù)的時候跳昼,因為b
內(nèi)部已經(jīng)進行了處理肋乍,那么就可以正常的調(diào)用墓造。
再來看看調(diào)用c
的情況滔岳,因為字符串s
是null,所以嘗試獲得一個length
的時候摊求,是會發(fā)生空指針異常的室叉,但是這個空指針異常又和上面的MyException
不同茧痕,空指針異常是個非檢查型異常
恼除,Java沒有規(guī)定必須處理,可以處理令野,也可以不處理气破。
如果不進行處理餐抢,那么一但拋出這個異常,就是Java就會認為是程序邏輯有問題碳锈,從而停止這個正在運行的程序,所以在調(diào)用c
之后的打印函數(shù)售碳,是不會打印出來東西的渗稍。但是為了保證程序不會因為這種邏輯異常不會停止,也進行try...catch
的話报强,那么也就是處理了這個異常灸姊,就不會被強制停止線程的運行。
關于自定義異常
自定義異常一般是繼承于Exception
類秉溉×撸可以看一下Exception
的源代碼。
public class Exception extends Throwable {
static final long serialVersionUID = -3387516993124229948L;
public Exception() {
super();
}
public Exception(String message) {
super(message);
}
public Exception(String message, Throwable cause) {
super(message, cause);
}
public Exception(Throwable cause) {
super(cause);
}
protected Exception(String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
刪掉一些注釋就會妨礙吸納召嘶,其實這個Exception
類什么都沒有父晶,都是針對不同參數(shù)的構造函數(shù),但是構造函數(shù)其實都是直接調(diào)用的是Throwable
的構造函數(shù)弄跌,也沒有做一些其他的事情甲喝。
那么既然是這樣的話,那么是不是自定義的異常類铛只,直接繼承Throwable
和繼承Exception
效果其實一樣的呢埠胖?應該是的。
本來還想再看一下Throwable
的源代碼的淳玩,的確也看了,但是看到一些native
的方法就不想貼出來了谋竖。
下面就是一個很經(jīng)典的自定義的異常類悄雅。
public class MyException extends Exception {
public MyException() {
}
//這里可以不用顯示地調(diào)用super()沿腰,因為函數(shù)里面沒有其他東西
//如果有其他東西的話纽什,那么還是需要使用super()進行顯示調(diào)用的
public MyException(String msg) {
}
}
其實自定義的異常類,最重要的是異常的名字,通過自定義異常笋婿,然后拋出自定義的異常元镀,可以清楚地通過異常的名字,看到具體是什么異常被拋出了,從而清楚地定位問題。
題外話
最近在進行Web開發(fā)的時候一直在想一個問題,比如有個查詢數(shù)據(jù)庫的操作冰更,這個查詢操作舟铜,可能會返回null
归斤,也可能會返回n條紀錄(如果為null的話,那么很有可能在外層引起空指針異常),那么如果返回null
的話,是在底層就將其使用異常機制拋出,強行告訴外層進行異常捕獲,還是說什么都不做,在外層通過判斷是否為null進行處理呢关面?