Java異常處理機(jī)制

世界上并不存在不會出錯的系統(tǒng)萍聊,只要是軟件系統(tǒng)就一定會在運(yùn)行的過程中出現(xiàn)開發(fā)人員無法預(yù)料的錯誤惩淳。如何處理意外發(fā)生就是我們作為一名開發(fā)人員所必須深入思考的問題惫撰。

Java語言提供了完善的異常處理機(jī)制然眼,它有效的降低了編寫以及維護(hù)的門檻(這也是Java語言大行其道的原因甘邀,好上手,機(jī)制全)遂蛀。今天在這里和大家分享一下Java異常機(jī)制的特點(diǎn)以及應(yīng)用谭跨。

現(xiàn)在我們回想一下干厚,在日常開發(fā)中我們常常用到try……catch……語句李滴,比如寫一個文件輸入輸出流,此時我們必須catch相應(yīng)的IOException蛮瞄、FileNotFountException所坯,否則編譯不通過,這里catch的是什么東西挂捅?答案是“Exception”芹助。平時我們在系統(tǒng)運(yùn)行中發(fā)現(xiàn)系統(tǒng)崩潰,比如OutOfMemoryError錯誤闲先,這個OOM是什么東西状土?答案是“Error”。綜上所述伺糠,Java中的異常分為兩大類蒙谓,Exception和Error,它們都繼承了Throwable類(只有集成了Throwable類才能被拋出或者捕獲)训桶。

一累驮、Exception與Error

Error是指正常情況下不大可能出現(xiàn)的情況酣倾,一旦出現(xiàn)很有可能導(dǎo)致程序處于不可恢復(fù)的非正常狀態(tài),開發(fā)人員不便于也不需要捕獲谤专。Exception則可以分為checked和unchecked異常躁锡,checked表示必須顯示捕獲處理,否則編譯不通過置侍。

Object Object
Throwable Throwable
Error Exception
LinkageError映之、VirtualMachineError unchecked、checked
NoClassDefFoundError和ClassNotFoundException有什么區(qū)別蜡坊?

NoClassDefFoundError是一個錯誤(Error)惕医,而ClassNotFoundException是一個異常(Exception),我們應(yīng)該嘗試從異常中恢復(fù)程序算色,而不應(yīng)該嘗試從錯誤中恢復(fù)程序抬伺。

ClassNotFoundException

ClassNotFoundException是一個checkedException,需要顯示捕獲處理灾梦。
ClassNotFoundException產(chǎn)生的原因是:Java使用Class.forName方法動態(tài)加載類到JVM內(nèi)存中峡钓,但是如果傳遞的類在類路徑中沒有被找到,那么就會拋出ClassNotFoundException異常若河。ClassLoader.loadClass能岩,ClassLoader.findSystemClass等方法在動態(tài)加載類到內(nèi)存中的時候也可能會跑出去這個異常。
還有一種導(dǎo)致ClassNotFoundException發(fā)生的原因萧福,當(dāng)一個類已經(jīng)被某個類加載器加載到內(nèi)存中了拉鹃,此時另一個類加載器又嘗試動態(tài)從同一個包中加載這個類。此時也會出現(xiàn)ClassNotFoundException異常鲫忍。
Demo:

public class Example {

    public static void main(String args[]) {
        try
        {
            Class.forName("GeeksForGeeks");
        }
        catch (ClassNotFoundException ex)
        {
            ex.printStackTrace();
        }
    }
}
NoClassDefFoundError

NoClassDefFoundError產(chǎn)生的原因是:JVM或者ClassLoader實(shí)例嘗試加載類的時候找不到類的定義膏燕。它是一個LlinkageError,LinkageError發(fā)生的情況是在一個類依賴另一個類悟民,而后者在前者編譯后又發(fā)生了改變坝辫。導(dǎo)致出現(xiàn)LinkageError的錯誤。
Demo:

class GeeksForGeeks  
{
    void greeting()
    {
        System.out.println("hello!");
    }
}
class G4G {
    public static void main(String args[])  
    {
        GeeksForGeeks geeks = new GeeksForGeeks();
        geeks.greeting();
    }
}

分別使用javac編譯兩個文件射亏,然后使用java G4G運(yùn)行近忙。當(dāng)我們把編譯后的GeeksForGeeks.class文件拿走后,就會報(bào)NoClassDefFoundError的錯誤智润。

二及舍、異常處理原則

通過上面的描述我們理解了Error和Exception之間的區(qū)別,接下來我們需要理解Java語言是如何操作Throwable元素窟绷【饴辏基本的語法包括“try-catch-finally”,“throw”钾麸,“throws”更振,“try-with-resources”等炕桨。異常處理有幾個原則需要遵守:
(1)盡量不要捕獲類似Exception這樣的通用異常,而應(yīng)該捕獲特定異常肯腕。
(2)不要生吞異常献宫。注意不要在生產(chǎn)環(huán)境使用e.printStackTrace()打印異常,最好使用產(chǎn)品日志实撒,詳細(xì)輸出到日志系統(tǒng)姊途。
(3)Throw early, catch late。提前把異常拋出來知态,或者構(gòu)建新的異常拋出去捷兰。這里就涉及到自定義異常,需要確定是否需要自定義checked Exception负敏;在保證診斷信息的同事避免敏感信息贡茅,比如java.net.ConnectException的出錯信息不包括機(jī)器名、IP其做、端口等敏感信息(日志信息也一樣顶考,不可以輸出用戶信息之類的敏感信息)。

有一種說法妖泄,提出Java語言的checkedException是一種設(shè)計(jì)錯誤驹沿。因?yàn)閏heckedException的初衷是希望捕獲異常,再從異常中回復(fù)正常蹈胡,但是大多數(shù)情況不能恢復(fù)渊季。另外checkedException不兼容functional編程(函數(shù)式編程,后續(xù)我會展開來講函數(shù)式編程罚渐、命令式編程的區(qū)別)述召,比如Lambda/Stream代碼(后續(xù)會詳細(xì)講Lambda的語法以及原理)居灯。但也有一部分人提出娶吞,確實(shí)有一些異常是可恢復(fù)的骡澈,比如IO異常冯事、網(wǎng)絡(luò)異常等败潦。

三嗡贺、異常處理與性能

處理異常會必然會增加代碼量讶隐,那么接下來我們從性能的角度來審視Java的異常處理機(jī)制赎懦。

  • try-catch代碼會影響JVM對代碼的優(yōu)化,所以不要用try包裹大段的代碼。
  • 不要試圖用異常捕獲來控制代碼流程态罪,比起if/else之類的語句地消,異常捕獲要更加低效。
  • Java實(shí)例化Exception都會對當(dāng)時的棧進(jìn)行快照当悔,該操作較重傅瞻。對于追求極致性能的底層類庫踢代,創(chuàng)建不進(jìn)行棧快照的Exception是一種方法嗅骄。但是這樣不利于我們定位問題胳挎,特別是在微服務(wù)這樣的分布式系統(tǒng),會增加診斷的難度溺森。當(dāng)服務(wù)變慢慕爬,吞度量下降時,檢查最頻繁的Exception是一種思路屏积。

四医窿、總結(jié)

通過本章的學(xué)習(xí),我們了解了Java異常中的兩大類:Exception與Error炊林。另外我們也學(xué)習(xí)了ClassNotFoundException和NoClassDefFoundError之間的區(qū)別姥卢。Java異常處理機(jī)制是Java語言一大特征,遵循異常處理原則可以有效提高代碼可讀性以及程序運(yùn)行的穩(wěn)定性渣聚。深入的掌握J(rèn)ava異常處理機(jī)制對我們Debug線上問題也有幫助隔显。

五、后記

回顧問題:

  1. Exception和Error有什么相同點(diǎn)饵逐、不通點(diǎn)括眠?
  2. 常見的CheckedException和RuntimeException有哪些?常見的Error有哪些倍权?
  3. NoClassDefFoundError和ClassNotFoundException有什么區(qū)別掷豺?

延伸問題:

  1. 為什么錯誤信息打印,不推薦使用e.printStackTrace()薄声?STERR為什么不是個合適的輸出項(xiàng)当船?
  2. 為什么使用try-catch來控制代碼流程,比起if-else更加低效默辨?
  3. 如何創(chuàng)建不進(jìn)行椀缕担快照的Exception?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缩幸,一起剝皮案震驚了整個濱河市壹置,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌表谊,老刑警劉巖钞护,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異爆办,居然都是意外死亡难咕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余佃,“玉大人暮刃,你說我怎么就攤上這事”粒” “怎么了椭懊?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雾消。 經(jīng)常有香客問我灾搏,道長,這世上最難降的妖魔是什么立润? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任狂窑,我火速辦了婚禮,結(jié)果婚禮上桑腮,老公的妹妹穿的比我還像新娘泉哈。我一直安慰自己,他們只是感情好破讨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布丛晦。 她就那樣靜靜地躺著,像睡著了一般提陶。 火紅的嫁衣襯著肌膚如雪烫沙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天隙笆,我揣著相機(jī)與錄音锌蓄,去河邊找鬼。 笑死撑柔,一個胖子當(dāng)著我的面吹牛瘸爽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铅忿,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼剪决,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了檀训?” 一聲冷哼從身側(cè)響起柑潦,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肢扯,沒想到半個月后妒茬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔚晨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铭腕。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡银择,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出累舷,到底是詐尸還是另有隱情浩考,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布被盈,位于F島的核電站析孽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏只怎。R本人自食惡果不足惜袜瞬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望身堡。 院中可真熱鬧邓尤,春花似錦、人聲如沸贴谎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽擅这。三九已至澈魄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仲翎,已是汗流浹背痹扇。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谭确,地道東北人帘营。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像逐哈,于是被迫代替她去往敵國和親芬迄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

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

  • 2.JAVA異常 異常指不期而至的各種狀況昂秃,如:文件找不到禀梳、網(wǎng)絡(luò)連接失敗、非法參數(shù)等肠骆。異常是一個事件算途,它發(fā)生在程...
    青城樓主閱讀 555評論 0 0
  • 本文部分來自于:代碼鋼琴家blog address:www.cnblogs.com/lulipro/p/75042...
    八目朱勇銘閱讀 1,317評論 0 4
  • 什么是異常? 異常本質(zhì)上是程序上的錯誤蚀腿,錯誤在我們編寫程序的過程中會經(jīng)常發(fā)生嘴瓤,包括編譯期間和運(yùn)行期間的錯誤扫外。 編譯...
    若兮緣閱讀 3,358評論 0 11
  • [toc] Java語言在設(shè)計(jì)之初就提供了相對完善的異常處理機(jī)制,大大提高了程序的可靠性廓脆。 異常的分類 我們編寫的...
    52718閱讀 444評論 0 1
  • 異常指不期而至的各種狀況筛谚,如:文件找不到、網(wǎng)絡(luò)連接失敗停忿、非法參數(shù)等驾讲。異常是一個事件,它發(fā)生在程序運(yùn)行期間席赂,干擾了正...
    誰吃了我的薯?xiàng)l閱讀 239評論 0 0