一.異常的概念
異常:就是程序運(yùn)行過程中,出現(xiàn)了非正常的情況,異常也是錯(cuò)誤的一種,但不是所有錯(cuò)誤都是異常,異常會(huì)導(dǎo)致JVM非正常停止。
異常有的時(shí)候是因?yàn)橛脩翦e(cuò)誤引起,有的時(shí)候是程序錯(cuò)誤引起的,還有的一些是其他原因?qū)е碌摹?/p>
二.異常的體系
異常在java當(dāng)中是以對(duì)象來處理的,異常的基類是:java.lang.Throwable
異常基類下有兩個(gè)子類:java.lang.Error和java.lang.Exception,即上面所說的錯(cuò)誤和異常。

異常體系.png
上圖列舉了Throwable的主要分支和一些常見的異常。
注意:
Error和Exception的區(qū)別:Error通常是災(zāi)難性的致命的錯(cuò)誤,是程序無法控制和處理的,當(dāng)出現(xiàn)這些異常時(shí),Java虛擬機(jī)(JVM)一般會(huì)選擇終止線程;Exception通常情況下是可以被程序處理的,并且在程序中應(yīng)該盡可能的去處理這些異常。
三.異常的分類
異常的分類,根據(jù)在編譯時(shí)期還是運(yùn)行時(shí)期檢查異??梢苑譃閮深悾?/p>
1.編譯時(shí)期異常(檢測(cè)異常):在編譯時(shí)期就會(huì)檢測(cè),如果沒有處理異常,則編譯失敗。
2.運(yùn)行時(shí)期異常(非檢測(cè)異常):在編譯時(shí)期不會(huì)檢測(cè)(也不會(huì)報(bào)錯(cuò))。
注意:
除了RuntimeException以及其子類外,其他的所有Exception類及其子類都是檢測(cè)異常,都是需要檢查的,當(dāng)出現(xiàn)這些異常時(shí),要么使用try-catch語句捕獲異常,要么用throws語句拋出異常,否則編譯無法通過。
而RuntimeException,這類異常時(shí)不檢測(cè)的,可以處理,但不一定會(huì)處理,一般不處理。
四.異常的處理
異常的處理本質(zhì)上有兩個(gè):拋出異常和捕獲異常。
簡單點(diǎn)說:
1.拋出異常:就是自己不處理,向上拋出異常,由調(diào)用者去決定怎么處理。
比如方法中對(duì)參數(shù)做檢測(cè):

捕獲異常:就是自己捕獲異常,并處理,處理捕獲異常需要使用try-catch語句(下面會(huì)講到)
五.異常處理的語法
異常處理的語法主要是五個(gè)關(guān)鍵字:try catch finally throw throws
try:用于監(jiān)測(cè),將可能產(chǎn)生異常的代碼放到try語句塊之中,當(dāng)異常產(chǎn)生時(shí),異常就會(huì)被拋出。
catch:用于捕獲異常,catch用來捕獲try語句塊中拋出的異常。
finally:finally語句塊的代碼總是會(huì)被執(zhí)行,主要是做一些清理(比如關(guān)閉打開了的文件句柄等),當(dāng)try或catch語句塊中有return語句或者throw語句,總是先執(zhí)行完finally語句塊,在返回執(zhí)行try或catch中的return語句或throw語句,所以如果finally中使用了return或者throw等終止方法的語句,就不會(huì)再返回了,方法會(huì)直接停止,所以不能再finally中使用return或者throw
throw:用于拋出異常
throws:用于在方法聲明中,聲明該方法可能拋出的異常
捕獲異常處理
try-catch語句處理

比如:

如何獲取異常信息?
答:在Throwable類中定義了一些查看方法,有以下三種:
public String getMessage():獲取異常的描述信息,錯(cuò)誤原因
public String toString():獲取異常的類型和異常的描述信息
public String printStackTrace():打印異常的跟著棧信息并輸出到控制臺(tái)
一般在開發(fā)和調(diào)試階段,都得使用printStackTrace,其包含了異常的類型,異常的原因,以及異常出現(xiàn)的位置。
2.try-catch-catch-...多個(gè)catch情況
有時(shí)候一個(gè)代碼段可以引發(fā)多個(gè)異常,這種情況可以定義多個(gè)catch,對(duì)每一種類型的異常進(jìn)行捕獲,當(dāng)異常發(fā)生時(shí)候,每個(gè)catch語句會(huì)依次檢查,第一個(gè)匹配異常類型的catch語句執(zhí)行,其他的所有catch語句不會(huì)再執(zhí)行.
編寫多個(gè)catch語句的注意事項(xiàng):子類在前,父類在后。
3.try-catch-finally
同try-catch或try-catch-catch-...,唯一的不同就是finally語句塊里的無論異常是否發(fā)生,都會(huì)執(zhí)行,并且不能在finally中添加return。
●拋出異常處理
1.使用throw拋出
具體語法:throw XXXException
如果throw語句在try塊里,則會(huì)檢查是否有匹配的catch語句,如果發(fā)現(xiàn)了有匹配的,則轉(zhuǎn)向?qū)?yīng)catch語句;如果沒有發(fā)現(xiàn),默認(rèn)的異常處理程序則會(huì)中斷程序,并且打印堆棧信息。
注意:程序執(zhí)行完throw語句之后立即停止,throw后面的語句不會(huì)被執(zhí)行。
比如:
class Throw Test{
? ? ? publi cstatic func () {
? ? ? ? ? ? ? ? ?try{
? ? ? ? ? ? ? ? ? ? ? throw new NullPointerException("Test");
? ? ? ? ? ? ? ? ? } catch (NullPointerException e) {
? ? ? ? ? ? ? ? ? ? ? ?throw e;
? ? ? ? ? ? ? ? ? }
? }
public static void main (String[] args ) {
? ? ?try {?
? ? ? ? ? ? ?func();
? ? ? ? ?} catch (NullPointerException e) {
? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? ?}
? ? }
}
/*
? 程序中兩次處理了異常,第一次,在main中調(diào)用func函數(shù)時(shí)候,拋出了異常,但func函數(shù)的try-catch捕獲了這個(gè)異常,在catch里又一次拋出了異常,給到了調(diào)用者main函數(shù),main里的try-catch進(jìn)行了捕獲,最后調(diào)用printStackTrace()
*/
2.throws聲明異常
如果一個(gè)方法可能產(chǎn)生一個(gè)異常,但本身不處理它,則必須在方法聲明中使用throws聲明異常,否則導(dǎo)致編譯錯(cuò)誤。
使用方法如下,如果存在多個(gè)異常,則用逗號(hào)隔開
public void func() throws Exception1,Exception2,...
注意:
關(guān)于throws拋出異常的規(guī)則如下:
如果是不檢測(cè)的異常,即Error,RuntimeException或其子類,可以不用throws聲明要拋出異常,也可以不用try-catch捕獲,編譯仍可以通過,但在運(yùn)行時(shí)會(huì)被系統(tǒng)拋出。
對(duì)于檢測(cè)的異常,要么用try-catch語句捕獲,要么用throw拋出異常,再用throws聲明異常,否則會(huì)導(dǎo)致編譯錯(cuò)誤。
當(dāng)拋出了異常給調(diào)用者,調(diào)用者也無法處理異常時(shí),必須要繼續(xù)拋出,不能置之不理。
如果要覆蓋一個(gè)方法,則聲明的任何異常必須是被覆蓋方法所聲明的異常的同類或子類。
六.自定義異常
除了使用java內(nèi)置的異常類外,還可以自定義異常,用戶自定義異常,只需要繼承Exception類即可
自定義異常,可以分為以下幾個(gè)步驟:
1.創(chuàng)建自定義異常類
2.在方法中通過throw拋出異常對(duì)象
3.如果在當(dāng)前拋出異常的方法中處理異常,可以使用try-catch捕獲并處理;否則在方法的聲明使用throws聲明要拋出的異常
4.在異常出現(xiàn)的方法中捕獲并處理異常
比如:模擬注冊(cè)操作,用戶名存在,則拋出異常并提示


原文鏈接:http://www.itdecent.cn/p/afd9e68feec2