java異常處理1(基本技術(shù))

一、簡介

????程序運行時帕膜,發(fā)生的不被期望的事件枣氧,它阻止了程序按照程序員的預(yù)期正常執(zhí)行,這就是異常垮刹。異常發(fā)生時达吞,是任程序自生自滅,立刻退出終止荒典,還是輸出錯誤給用戶酪劫?或者用C語言風(fēng)格:用函數(shù)返回值作為執(zhí)行狀態(tài)?寺董。

Java提供了更加優(yōu)秀的解決辦法:異常處理機制覆糟。

????異常處理機制能讓程序在異常發(fā)生時,按照代碼的預(yù)先設(shè)定的異常處理邏輯遮咖,針對性地處理異常滩字,讓程序盡最大可能恢復(fù)正常并繼續(xù)執(zhí)行,且保持代碼的清晰盯滚。

????Java中的異程咝担可以是函數(shù)中的語句執(zhí)行時引發(fā)的酗电,也可以是程序員通過throw 語句手動拋出的魄藕,只要在Java程序中產(chǎn)生了異常,就會用一個對應(yīng)類型的異常對象來封裝異常撵术,JRE就會試圖尋找異常處理程序來處理異常背率。

????Throwable類是Java異常類型的頂層父類,一個對象只有是 Throwable 類的(直接或者間接)實例嫩与,他才是一個異常對象寝姿,才能被異常處理機制識別。JDK中內(nèi)建了一些常用的異常類纠脾,我們也可以自定義異常涧卵。

Java異常的分類和類結(jié)構(gòu)圖

????Java標(biāo)準(zhǔn)庫內(nèi)建了一些通用的異常暑塑,這些類以Throwable為頂層父類。

????Throwable又派生出Error類和Exception類根资。

????錯誤:Error類以及他的子類的實例架专,代表了JVM本身的錯誤。錯誤不能被程序員通過代碼處理玄帕,Error很少出現(xiàn)部脚。因此,程序員應(yīng)該關(guān)注Exception為父類的分支下的各種異常類裤纹。

????異常:Exception以及他的子類委刘,代表程序運行時發(fā)送的各種不期望發(fā)生的事件∮ソ罚可以被Java異常處理機制使用锡移,是異常處理的核心。


java異常類圖

總體上我們根據(jù)Javac對異常的處理要求漆际,將異常類分為2類:

非檢查異常(unckecked exception):

????Error 和 RuntimeException 以及他們的子類罩抗。javac在編譯時,不會提示和發(fā)現(xiàn)這樣的異常灿椅,不要求在程序處理這些異常套蒂。所以如果愿意,我們可以編寫代碼處理(使用try…catch…finally)這樣的異常茫蛹,也可以不處理操刀。對于這些異常,我們應(yīng)該修正代碼婴洼,而不是去通過異常處理器處理 骨坑。這樣的異常發(fā)生的原因多半是代碼寫的有問題。如除0錯誤ArithmeticException柬采,錯誤的強制類型轉(zhuǎn)換錯誤ClassCastException欢唾,數(shù)組索引越界ArrayIndexOutOfBoundsException,使用了空對象NullPointerException等等粉捻。

檢查異常(checked exception):

????除了Error 和 RuntimeException的其它異常礁遣。javac強制要求程序員為這樣的異常做預(yù)備處理工作(使用try…catch…finally或者throws)。在方法中要么用try-catch語句捕獲它并處理肩刃,要么用throws子句聲明拋出它祟霍,否則編譯不會通過。這樣的異常一般是由程序的運行環(huán)境導(dǎo)致的盈包。因為程序可能被運行在各種未知的環(huán)境下沸呐,而程序員無法干預(yù)用戶如何使用他編寫的程序,于是程序員就應(yīng)該為這樣的異常時刻準(zhǔn)備著呢燥。如SQLException , IOException,ClassNotFoundException 等崭添。

需要明確的是:檢查和非檢查是對于javac來說的,這樣就很好理解和區(qū)分了叛氨。

二呼渣、異常處理

1.認(rèn)識異常


一個簡單的除法器


除法器的除0異常

????異常是在執(zhí)行某個函數(shù)時引發(fā)的根暑,而函數(shù)又是層級調(diào)用,形成調(diào)用棧的徙邻,因為排嫌,只要一個函數(shù)發(fā)生了異常,那么他的所有的caller都會被異常影響缰犁。當(dāng)這些被影響的函數(shù)以異常信息輸出時淳地,就形成的了異常追蹤棧。異常最先發(fā)生的地方帅容,叫做異常拋出點颇象。

? ??從上面的例子可以看出,當(dāng)devide函數(shù)發(fā)生除0異常時并徘,devide函數(shù)將拋出ArithmeticException異常遣钳,因此調(diào)用他的CMDCalculate函數(shù)也無法正常完成,因此也發(fā)送異常麦乞,而CMDCalculate的caller——main 因為CMDCalculate拋出異常蕴茴,也發(fā)生了異常,這樣一直向調(diào)用棧的棧底回溯姐直。這種行為叫做異常的冒泡倦淀,異常的冒泡是為了在當(dāng)前發(fā)生異常的函數(shù)或者這個函數(shù)的caller中找到最近的異常處理程序。由于這個例子中沒有使用任何異常處理機制声畏,因此異常最終由main函數(shù)拋給jre撞叽,導(dǎo)致程序終止。

????上面的代碼不使用異常處理機制插龄,也可以順利編譯愿棋,因為2個異常都是非檢查異常。但是下面的例子就必須使用異常處理機制均牢,因為異常是檢查異常糠雨。

檢查異常實例


????代碼中我選擇使用throws聲明異常,讓函數(shù)的調(diào)用者去處理可能發(fā)生的異常膨处。但是為什么只throws了IOException呢见秤?因為FileNotFoundException是IOException的子類,在處理范圍內(nèi)真椿。

2.異常處理的基本語法

????在編寫代碼處理異常時,對于檢查異常乎澄,有2種不同的處理方式:使用try…catch…finally語句塊處理它突硝。或者置济,在函數(shù)簽名中使用throws 聲明交給函數(shù)調(diào)用者caller去解決解恰。

? ??try…catch…finally語句塊


try{

?????//try塊中放可能發(fā)生異常的代碼锋八。

?????//如果執(zhí)行完try且不發(fā)生異常,則接著去執(zhí)行finally塊和finally后面的代碼(如果有的話)护盈。

?????//如果發(fā)生異常挟纱,則嘗試去匹配catch塊。


}catch(SQLException SQLexception){

????//每一個catch塊用于捕獲并處理一個特定的異常腐宋,或者這異常類型的子類紊服。Java7中可以將多個異常聲明在一個catch中。

????//catch后面的括號定義了異常類型和異常參數(shù)胸竞。如果異常與之匹配且是最先匹配到的欺嗤,則虛擬機將使用這個catch塊來處理異常。

????//在catch塊中可以使用這個塊的異常參數(shù)來獲取異常的相關(guān)信息卫枝。異常參數(shù)是這個catch塊中的局部變量煎饼,其它塊不能訪問。

????//如果當(dāng)前try塊中發(fā)生的異常在后續(xù)的所有catch中都沒捕獲到校赤,則先去執(zhí)行finally吆玖,然后到這個函數(shù)的外部caller中去匹配異常處理器。

????//如果try中沒有發(fā)生異常马篮,則所有的catch塊將被忽略衰伯。


}catch(Exception exception){

????//...

}finally{


????//finally塊通常是可選的。

???//無論異常是否發(fā)生积蔚,異常是否匹配被處理意鲸,finally都會執(zhí)行。

???//一個try至少要有一個catch塊尽爆,否則怎顾, 至少要有1個finally塊。但是finally不是用來處理異常的漱贱,finally不會捕獲異常槐雾。

??//finally主要做一些清理工作,如流的關(guān)閉幅狮,數(shù)據(jù)庫連接的關(guān)閉等募强。

}

throws 函數(shù)聲明

????throws聲明:如果一個方法內(nèi)部的代碼會拋出檢查異常(checked exception),而方法自己又沒有完全處理掉崇摄,則javac保證你必須在方法的簽名上使用throws關(guān)鍵字聲明這些可能拋出的異常擎值,否則編譯不通過。

????throws是另一種處理異常的方式逐抑,它不同于try…catch…finally鸠儿,throws僅僅是將函數(shù)中可能出現(xiàn)的異常向調(diào)用者聲明,而自己則不具體處理。

????采取這種異常處理的原因可能是:方法本身不知道如何處理這樣的異常进每,或者說讓調(diào)用者處理更好汹粤,調(diào)用者需要為可能發(fā)生的異常負(fù)責(zé)。

publicvoidfoo() throwsExceptionType1 , ExceptionType2 ,ExceptionTypeN

{

????//foo內(nèi)部可以拋出 ExceptionType1 , ExceptionType2 ,ExceptionTypeN 類的異常田晚,或者他們的子類的異常對象嘱兼。

}

finally塊

????finally塊不管異常是否發(fā)生,只要對應(yīng)的try執(zhí)行了贤徒,則它一定也執(zhí)行芹壕。只有一種方法讓finally塊不執(zhí)行:System.exit()。因此finally塊通常用來做資源釋放操作:關(guān)閉文件泞莉,關(guān)閉數(shù)據(jù)庫連接等等哪雕。

良好的編程習(xí)慣是:在try塊中打開資源,在finally塊中清理釋放這些資源鲫趁。

需要注意的地方:

1斯嚎、finally塊沒有處理異常的能力。處理異常的只能是catch塊挨厚。

2堡僻、在同一try…catch…finally塊中 ,如果try中拋出異常疫剃,且有匹配的catch塊钉疫,則先執(zhí)行catch塊,再執(zhí)行finally塊巢价。如果沒有catch塊匹配牲阁,則先執(zhí)行finally,然后去外面的調(diào)用者中尋找合適的catch塊壤躲。

3城菊、在同一try…catch…finally塊中 ,try發(fā)生異常碉克,且匹配的catch塊中處理異常時也拋出異常凌唬,那么后面的finally也會執(zhí)行:首先執(zhí)行finally塊,然后去外圍調(diào)用者中尋找合適的catch塊漏麦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末客税,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子撕贞,更是在濱河造成了極大的恐慌更耻,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麻掸,死亡現(xiàn)場離奇詭異酥夭,居然都是意外死亡,警方通過查閱死者的電腦和手機脊奋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門熬北,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诚隙,你說我怎么就攤上這事讶隐。” “怎么了久又?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵巫延,是天一觀的道長。 經(jīng)常有香客問我地消,道長炉峰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任脉执,我火速辦了婚禮疼阔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘半夷。我一直安慰自己婆廊,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布巫橄。 她就那樣靜靜地躺著淘邻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪湘换。 梳的紋絲不亂的頭發(fā)上宾舅,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音彩倚,去河邊找鬼筹我。 笑死,一個胖子當(dāng)著我的面吹牛署恍,可吹牛的內(nèi)容都是我干的崎溃。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼盯质,長吁一口氣:“原來是場噩夢啊……” “哼袁串!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呼巷,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤囱修,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后王悍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體破镰,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鲜漩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片源譬。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖孕似,靈堂內(nèi)的尸體忽然破棺而出踩娘,到底是詐尸還是另有隱情,我是刑警寧澤喉祭,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布养渴,位于F島的核電站,受9級特大地震影響泛烙,放射性物質(zhì)發(fā)生泄漏理卑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一蔽氨、第九天 我趴在偏房一處隱蔽的房頂上張望藐唠。 院中可真熱鬧,春花似錦孵滞、人聲如沸中捆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泄伪。三九已至,卻和暖如春匿级,著一層夾襖步出監(jiān)牢的瞬間蟋滴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工痘绎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留津函,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓孤页,卻偏偏與公主長得像尔苦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子行施,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345