Java異常在日常的開發(fā)中簡直是司空見慣了,但自己還是想做一個(gè)整理,看這篇文章的人,如果覺得有所收獲,那就更好了。
自己想從3方面來介紹java異常;
1、異常的體系結(jié)構(gòu),
2、異常認(rèn)識,
3、一般異常處理的原則。
一、異常的體系結(jié)構(gòu)

? ???????Throwable類是所有異常的始祖,它有兩個(gè)直接子類Error?/?Exception。
????????Error?一般是指java虛擬機(jī)生成并拋出的相關(guān)問題,如系統(tǒng)崩潰(系統(tǒng)錯(cuò)誤)、虛擬機(jī)出錯(cuò)誤、動態(tài)鏈接失敗等,這種錯(cuò)誤無法恢復(fù)或不可能捕獲,將導(dǎo)致應(yīng)用程序中斷,通常應(yīng)用程序無法處理這些錯(cuò)誤,因此應(yīng)用程序不應(yīng)該捕獲Error對象,也無須在其throws子句中聲明該方法拋出任何Error或其子類。
????????Exception?的一種分類:Checked異常和Runtime異常。所有RuntimeException類及其子類的實(shí)例被稱為Runtime異常,不屬于該范疇的異常則被稱為CheckedException。
? ??????CheckedException:代表程序不能控制的無效外界情況。可以被處理的異常,如果沒有處理則無法編譯。沒有完善錯(cuò)誤處理的代碼根本沒有機(jī)會被執(zhí)行。除了Error以及RuntimeException及其子類,CheckedException處理方式有兩種:
? ? ? ? ? ? 1、當(dāng)前方法知道如何處理該異常,則調(diào)用try...catch...顯示捕獲
? ? ? ? ? ? 2、當(dāng)前方法不知道如何處理,則在定義該方法聲明拋出異常
? ? 常見的CheckedException有ClassNotFoundException, NamingException, ServletException, SQLException, IOException等。
? ? ? ? RuntimeException:所有RuntimeException的實(shí)例及其子類的實(shí)例。這些異??梢赃x擇捕獲處理、也可以不處理,一般由程序邏輯錯(cuò)誤引起(應(yīng)盡量從邏輯角度避免此類異常的發(fā)生)。
? ? ????常見的RuntimeException有ArithmeticException、ArrayStoreExcetpion、ClassCastException、NullPointerException、IndexOutOfBoundsException、IllegalArgumentException、NegativeArraySizeException、NumberFormatException、SecurityException、UnsupportedOperationException等等
? ? ? ? Exception的另一種分類:CheckedException和UncheckedException。
? ??????CheckedException:同上。【代表程序不能直接控制的無效外界情況(如用戶輸入,數(shù)據(jù)庫問題,網(wǎng)絡(luò)異常,文件丟失等),除了Error和RuntimeException及其子類之外,如:ClassNotFoundException, NamingException, ServletException, SQLException, IOException等。 需要try catch處理或throws聲明拋出異常。 】
? ??????UncheckedException:?指的是程序的瑕疵或邏輯錯(cuò)誤,并且在運(yùn)行時(shí)無法恢復(fù),包括Error與RuntimeException及其子類,如:OutOfMemoryError, UndeclaredThrowableException, IllegalArgumentException, IllegalMonitorStateException, NullPointerException, IllegalStateException, IndexOutOfBoundsException等;語法上不需要聲明拋出異常。
綜上:CheckedException 需要調(diào)用try...catch...顯示捕獲,而RuntimeException 不需要捕獲;CheckedException可以繼續(xù)執(zhí)行下去,不能繼續(xù)執(zhí)行下去的就是UncheckedException。
二、異常的認(rèn)識
????????Java中的異常用對象來表示。Java對異常的處理是按異常分類處理的,不同異常有不同的分類,每種異常都對應(yīng)一個(gè)類型(class),每個(gè)異常都對應(yīng)一個(gè)異常(類的)對象,這樣就可以將異常情況與異常類一一對應(yīng),從拋出的異常類就可以知道是什么異常了。
Java有2種異常,一種是Java語言本身定義的一些基本異常類型(一般我們熟悉的異常類都是),一種是用戶通過繼承Exception類或者其子類自己定義的異常,這類異常主要是針對項(xiàng)目本身情況定義的異常。
Java異常處理主要通過關(guān)鍵字try、catch、throw、throws、finally進(jìn)行管理。基本過程是用try語句塊包住要監(jiān)視的語句,如果在try語句塊內(nèi)出現(xiàn)異常,則異常會被拋出,你的代碼在catch語句塊中可以捕獲到這個(gè)異常并做處理;還有以部分系統(tǒng)生成的異常在Java運(yùn)行時(shí)自動拋出。你也可以通過throws關(guān)鍵字在方法上聲明該方法要拋出異常,然后在方法內(nèi)部通過throw拋出異常對象。finally語句塊會在方法執(zhí)行return之前執(zhí)行。
三、異常處理
????????Java異常處理涉及到五個(gè)關(guān)鍵字,分別是:try、catch、finally、throw、throws。下面將驟一介紹,通過認(rèn)識這五個(gè)關(guān)鍵字,掌握基本異常處理知識。
? ????1、try:它里面放置可能引發(fā)異常的代碼
? ????2、catch:后面對應(yīng)異常類型和一個(gè)代碼塊,用于表明該catch塊用于處理這種類型的代碼塊,可以有多個(gè)catch塊。
? ????3、finally:主要用于回收在try塊里打開的物理資源(如數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接和磁盤文件),異常機(jī)制總是保證finally塊總是被執(zhí)行。只有finally塊,執(zhí)行完成之后,才會回來執(zhí)行try或者catch塊中的return或者throw語句,如果finally中使用了return或者throw等終止方法的語句,則就不會跳回執(zhí)行,直接停止。
(對于這個(gè)說的順序,大師兄我做了個(gè)測試,可以看下,鏈接:親自測試下try catch finally 的執(zhí)行順序)
? ????4、throw:用于拋出一個(gè)實(shí)際的異常,可以單獨(dú)作為語句使用,拋出一個(gè)具體的異常對象。
? ????5、throws:用在方法簽名中,用于聲明該方法可能拋出的異常。
? ? ? 其中,?try、catch、finally三個(gè)語句塊應(yīng)注意的問題
? ?(1)try、catch、finally三個(gè)語句塊均不能單獨(dú)使用,三者可以組成 try...catch...finally、try...catch、try...finally三種結(jié)構(gòu),catch語句可以有一個(gè)或多個(gè),finally語句最多一個(gè)。
? ?(2)try、catch、finally三個(gè)代碼塊中變量的作用域?yàn)榇a塊內(nèi)部,分別獨(dú)立而不能相互訪問。如果要在三個(gè)塊中都可以訪問,則需要將變量定義到這些塊的外面。
?? (3)多個(gè)catch塊時(shí)候,最多只會匹配其中一個(gè)異常類且只會執(zhí)行該catch塊代碼,而不會再執(zhí)行其它的catch塊,且匹配catch語句的順序?yàn)閺纳系较拢部赡芩械腸atch都沒執(zhí)行。
? ?(4)先Catch子類異常再Catch父類異常。
? ?(5)Finally:當(dāng)在try塊或catch塊中遇到return語句時(shí),finally語句塊將在方法返回之前被執(zhí)行。在以下4種特殊情況下,finally塊不會被執(zhí)行:
????????1)在finally語句塊中發(fā)生了異常。
????????2)在前面的代碼中用了System.exit()退出程序。
????????3)程序所在的線程死亡。
????????4)關(guān)閉CPU。
? ? ? 其中,throw與throws關(guān)鍵字的區(qū)別
????(1)throw關(guān)鍵字是用于方法體內(nèi)部,用來拋出一個(gè)Throwable類型的異常。如果拋出了檢查異常,則還應(yīng)該在方法頭部聲明方法可能拋出的異常類型。該 方法的調(diào)用者也必須檢查處理拋出的異常。如果所有方法都層層上拋獲取的異常,最終JVM會進(jìn)行處理,處理也很簡單,就是打印異常消息和堆棧信息。如果拋出 的是Error或RuntimeException,則該方法的調(diào)用者可選擇處理該異常。
????(2)throws關(guān)鍵字用于方法體外部的方法聲明部分,用來聲明方法可能會拋出某些異常。僅當(dāng)拋出了檢查異常,該方法的調(diào)用者才必須處理或者重新拋出該異常。當(dāng)方法的調(diào)用者無力處理該異常的時(shí)候,應(yīng)該繼續(xù)拋出,而不是囫圇吞棗一般在catch塊中打印一下堆棧信息做個(gè)勉強(qiáng)處理。