Java異常處理

1.什么是Java異常?

? ? ? ?今天我們來(lái)聊聊java異常,異常時(shí)導(dǎo)致程序中斷執(zhí)行的一種指令流包雀。我們?cè)谔岣叽a穩(wěn)定性和健壯性的時(shí)候,常常會(huì)花更多的時(shí)間去考慮亲铡,代碼可能存在的異常才写。編碼中對(duì)可能的發(fā)生的異常先一步正確處理,就可以確保異常不會(huì)導(dǎo)致程序不可用奖蔓。說(shuō)了這么多異常赞草,那么異常是什么呢?

? ? ? ?Java異常是一種導(dǎo)致程序中斷的執(zhí)行指令流吆鹤。它存在應(yīng)用服務(wù)器硬件錯(cuò)誤厨疙、程序編寫(xiě)的時(shí)候未考慮數(shù)組越界、也可能是網(wǎng)絡(luò)通信中網(wǎng)絡(luò)抖動(dòng)的客觀原因?qū)е碌漠惓5惹闆r疑务。異痴雌啵可能是主觀代碼設(shè)計(jì)不周全也可能是客觀硬件報(bào)錯(cuò)存哲,那么認(rèn)識(shí)異常就是避免異常的第一步。我們先從異常家族的認(rèn)識(shí)開(kāi)始弥喉,下面異常的族譜:

? ? ? ?Throwable類(lèi)作為所有異常的發(fā)源鲫竞,他是整個(gè)Java異常體系的超體,其下面分為Error和Exception兩大類(lèi)鞠鲜。

?? ? ? ?Error與其子類(lèi)實(shí)例代表嚴(yán)重系統(tǒng)錯(cuò)誤,應(yīng)用程序無(wú)法處理,如硬件層面的錯(cuò)誤嗤朴、JVM錯(cuò)誤或內(nèi)存不足等問(wèn)題,這種錯(cuò)誤發(fā)生時(shí)Java應(yīng)用程序本身無(wú)力恢復(fù)虫溜。Error對(duì)象拋出時(shí)雹姊,基本上不用處理,任其傳播至JVM為止衡楞,應(yīng)用程序能做的最多留下日志信息吱雏。

? ? ? ?Exception代表程序運(yùn)行時(shí)發(fā)送的各種不期望發(fā)生的事件。可以被Java異常處理機(jī)制使用歧杏,是異常處理的核心镰惦。Exception及其子類(lèi)可以被程序處理,也就是所在應(yīng)用程序中正確的處理了Exception及其子類(lèi)就能提高代碼的穩(wěn)定性和健壯性犬绒。

? ? ? ?Exception類(lèi)下面分為檢測(cè)異常和非檢測(cè)異常:

? ? ? ?檢測(cè)異常旺入,是JVM強(qiáng)制要求程序員為可能出現(xiàn)的異常做預(yù)備處理工作。JVM規(guī)定檢測(cè)異常要么使用try-catch語(yǔ)句捕獲它并進(jìn)行處理凯力,要么使用throws子句聲明并拋出它茵瘾,否者javac在編譯程序會(huì)不通過(guò)。這類(lèi)異常一般是程序運(yùn)行環(huán)境導(dǎo)致的咐鹤,為了預(yù)防未知環(huán)境對(duì)程序的影響拗秘,規(guī)定程序員需要處理這類(lèi)異常。

? ? ? ?非檢測(cè)異常祈惶,javac在編譯時(shí)聘殖,不會(huì)提示和發(fā)現(xiàn)異常的存在,JVM不強(qiáng)制要求程序員處理這樣的異常行瑞。當(dāng)然奸腺,作為程序員我們應(yīng)該預(yù)防這樣的異常導(dǎo)致程序崩潰,所以建議使用try-catch-finally處理它血久。這類(lèi)異常原因多半是代碼寫(xiě)的邏輯有問(wèn)題或考慮不周全突照。

2.當(dāng)一個(gè)Exception在程序中發(fā)生的時(shí)候,JVM是怎么做的呢氧吐?

? ? ? ?對(duì)java整體異常家族有了大致的認(rèn)識(shí)之后讹蘑,那么當(dāng)一個(gè)Exception在程序中發(fā)生的時(shí)候,JVM是怎么做的呢筑舅?

? ? ? ?認(rèn)識(shí)這個(gè)問(wèn)題座慰,我們首看看JVM是如何執(zhí)行java代碼的,按照?qǐng)?zhí)行步驟可以分為翠拣,JVM將class文件轉(zhuǎn)換為JVM的java類(lèi)版仔。JVM為java類(lèi)建立方法表,方法表中的索引可以引導(dǎo)JVM找到需要執(zhí)行的方法體和JVM方法執(zhí)行棧误墓。當(dāng)然蛮粮,invokemethod調(diào)用執(zhí)行一個(gè)方法的時(shí)候,Java虛擬機(jī)把描述該方法的棧結(jié)構(gòu)置入方法執(zhí)行棧棧頂谜慌,位于棧頂?shù)姆椒檎趫?zhí)行的方法然想。JVM會(huì)為每一個(gè)方法建立執(zhí)行的堆和棧用于存放執(zhí)行中的變量,如果此時(shí)程序出現(xiàn)一個(gè)Exception欣范,拋出的異常先轉(zhuǎn)移給合適的異常處理語(yǔ)句变泄。代碼的執(zhí)行會(huì)被相應(yīng)的Exception執(zhí)行流接管令哟,將方法表信息、發(fā)生異常的位置信息和方法的堆棧信息壓入Exception的堆棧妨蛹,當(dāng)程序中斷的時(shí)候IDE就會(huì)將Exception的堆棧信息打印出來(lái)励饵。

? ? ? ?如果我們通過(guò)try…..catch….finally語(yǔ)句來(lái)處理異常,處理流程又是怎樣的呢滑燃?在try代碼塊中拋出的異常役听,代碼執(zhí)行流會(huì)跳轉(zhuǎn)到catch代碼塊執(zhí)行,catch代碼塊可以對(duì)發(fā)生的異常進(jìn)行補(bǔ)救表窘。讓代碼回歸到正常的執(zhí)行流程典予。finally語(yǔ)句,無(wú)論在try模塊中是否發(fā)生異常乐严,都會(huì)執(zhí)行finally語(yǔ)句瘤袖,使用finally語(yǔ)句主要是為了釋放被占用的資源,比如打開(kāi)的文件或鏈接的通信資源等昂验。

? ? ? ?總體來(lái)說(shuō)捂敌,Java語(yǔ)言的異常處理流程,從程序中獲取異常信息既琴。根據(jù)Java的源文件和用戶(hù)調(diào)用的包列表占婉,JVM可以獲取該程序包括Java API所引發(fā)的異常在內(nèi)的異常處理的信息,這些信息包括:異常引發(fā)位置甫恩、異常拋出順序逆济、引發(fā)異常的方法名和類(lèi)名等。這些異常信息在程序異常的排查和修改的時(shí)候非常重要磺箕,后面會(huì)講到如何正確處理這些異常奖慌。

3.當(dāng)我們編寫(xiě)程序的時(shí)候如何對(duì)待可能出現(xiàn)的異常呢?

? ? ? ?通常在發(fā)生異常的時(shí)候我們有兩種處理模型:終止與恢復(fù)松靡。

? ? ? ?終止模型:前提是假設(shè)錯(cuò)誤非常關(guān)鍵简僧,以至于程序無(wú)法返回到程序正常運(yùn)行軌跡,一旦異常拋出就意味著程序?qū)⑼V固峁┓?wù)雕欺。如:數(shù)據(jù)庫(kù)連接異常發(fā)生

? ? ? ?恢復(fù)模型:也就是異常程序發(fā)生錯(cuò)誤岛马,錯(cuò)誤可以被修復(fù)然后重新回到正常程序執(zhí)行的軌跡上。例如阅茶,我們可以將數(shù)據(jù)庫(kù)連接try蛛枚。。脸哀。catch置于循環(huán)中,一次連接不成功可以循環(huán)下一次進(jìn)行連接扭吁。

? ? ? ?配合終止和恢復(fù)模型撞蜂,我們會(huì)配合使用throw和throws語(yǔ)法盲镶。throws關(guān)鍵字主要在方法簽名中使用,用于聲明該方法可能拋出的異常蝌诡。throws 可以理解成是一種通知行為溉贿,沒(méi)有實(shí)際的拋出異常的動(dòng)作,而僅僅是告訴調(diào)用他的上層函數(shù)浦旱,這里可能會(huì)拋出這個(gè)異常;

? ? ? ?throw用于在函數(shù)體內(nèi)語(yǔ)句中宇色,表示拋出一個(gè)實(shí)際的異常的實(shí)際動(dòng)作,如果在函數(shù)內(nèi)沒(méi)有捕獲并處理颁湖,那么將會(huì)一直向上拋出這個(gè)異常直到被main()/Thread.run()拋出宣蠕。

? ? ? ?我們了解了Java的異常內(nèi)容之后,在程序中遵循怎樣的行業(yè)規(guī)則和大牛的經(jīng)驗(yàn)合理使用異常甥捺,提高代碼的穩(wěn)定性呢抢蚀?

? ? ? ?下面整理了包括Effective Java異常使用指導(dǎo)原則和網(wǎng)上博客內(nèi)容:

1.? ?不要講異常處理用于正常的控制流(設(shè)計(jì)良好的API不應(yīng)該強(qiáng)迫它的調(diào)用者為了正常的控制流而使用異常)。

2.? ? 對(duì)可以恢復(fù)的情況使用了受檢異常镰禾,對(duì)編程錯(cuò)誤使用運(yùn)行時(shí)異常皿曲。

3.? ? 避免不必要的使用受檢異常(可以通過(guò)一些狀態(tài)檢測(cè)手段來(lái)避免異常的發(fā)生)。

4.? ? 優(yōu)先使用標(biāo)準(zhǔn)異常吴侦。

5.? ? 每個(gè)方法拋出的異常都要有文檔屋休。

6.? ? 保持異常的原子性。

7.? ? 不要再catch中忽略掉捕獲到的異常备韧。

8.? ? 處理運(yùn)行時(shí)異常博投,采用邏輯合理規(guī)避同時(shí)輔助try…catch處理。

9.? ? 在多重catch快后面盯蝴,可以加一個(gè)catch(Exception)來(lái)處理可能會(huì)被遺漏的異常毅哗。

10.? 對(duì)于不確定的代碼,也可以加上try…catch捧挺,處理潛在的異常虑绵。

11.? 盡量去處理異常,切忌只是簡(jiǎn)單的調(diào)用printStackTrace()打印輸出闽烙。

12.? 具體如何處理異常翅睛,要根據(jù)不同的業(yè)務(wù)需求和異常類(lèi)型去決定。

13.? 盡量添加finally語(yǔ)句塊去釋放占用的資源黑竞。

? ? ? ?不要被這么多規(guī)則嚇到了捕发,不需要逐條強(qiáng)記他們。我對(duì)異常的理解很魂,首先態(tài)度上要謙虛明白代碼中很難避免因?yàn)榭紤]不周出現(xiàn)的異常扎酷,所以編碼時(shí)應(yīng)該采用防衛(wèi)式編碼。其次在編碼處理過(guò)程中使用try…catch…finally語(yǔ)句預(yù)防可能的異常遏匆,采用合適的異常處理模式對(duì)待程序可能的異常法挨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谁榜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子凡纳,更是在濱河造成了極大的恐慌窃植,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荐糜,死亡現(xiàn)場(chǎng)離奇詭異巷怜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)暴氏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)延塑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人偏序,你說(shuō)我怎么就攤上這事页畦。” “怎么了研儒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵豫缨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我端朵,道長(zhǎng)好芭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任冲呢,我火速辦了婚禮舍败,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘敬拓。我一直安慰自己邻薯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布乘凸。 她就那樣靜靜地躺著厕诡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪营勤。 梳的紋絲不亂的頭發(fā)上灵嫌,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音葛作,去河邊找鬼寿羞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赂蠢,可吹牛的內(nèi)容都是我干的绪穆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼霞幅!你這毒婦竟也來(lái)了漠吻?” 一聲冷哼從身側(cè)響起量瓜,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤司恳,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后绍傲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體扔傅,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年烫饼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猎塞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杠纵,死狀恐怖荠耽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情比藻,我是刑警寧澤铝量,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站银亲,受9級(jí)特大地震影響慢叨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜务蝠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一拍谐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馏段,春花似錦轩拨、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至够坐,卻和暖如春寸宵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背元咙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工梯影, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人庶香。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓甲棍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赶掖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子感猛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 2.JAVA異常 異常指不期而至的各種狀況七扰,如:文件找不到、網(wǎng)絡(luò)連接失敗陪白、非法參數(shù)等颈走。異常是一個(gè)事件,它發(fā)生在程...
    青城樓主閱讀 549評(píng)論 0 0
  • 六種異常處理的陋習(xí) 你覺(jué)得自己是一個(gè)Java專(zhuān)家嗎咱士?是否肯定自己已經(jīng)全面掌握了Java的異常處理機(jī)制立由?在下面這段代...
    Executing閱讀 1,316評(píng)論 0 6
  • 初識(shí)異常(Exception) 比如我們?cè)谌?shù)組里面的某個(gè)值得時(shí)候,經(jīng)常會(huì)出現(xiàn)定義的取值范圍超過(guò)了數(shù)組的大小序厉,那么...
    iDaniel閱讀 1,864評(píng)論 1 2
  • 概念介紹 異常是發(fā)生在程序執(zhí)行過(guò)程中阻礙程序正常執(zhí)行的錯(cuò)誤事件锐膜,當(dāng)一個(gè)程序出現(xiàn)錯(cuò)誤時(shí),可能的情況有如下3種: 語(yǔ)法...
    niaoge2016閱讀 5,161評(píng)論 2 20
  • 3月7日凌晨0點(diǎn)55分弛房,躺在床上道盏,我在想我是誰(shuí)。 在躺在床上之前一刻文捶,我都堅(jiān)信荷逞,今天交不了作業(yè)了。因?yàn)橥砩?點(diǎn)半回...
    花椒抹茶酥閱讀 133評(píng)論 0 0