您好,登錄后才能下訂單哦!
異常的概念
異常是程序中的一些錯(cuò)誤,但并不是所有的錯(cuò)誤都是異常,并且錯(cuò)誤有時(shí)候是可以避免的。
比如說,你的代碼少了一個(gè)分號(hào),那么運(yùn)行出來結(jié)果是提示是錯(cuò)誤java.lang.Error;如果你用System.out.println(11/0),那么你是因?yàn)槟阌?做了除數(shù),會(huì)拋出java.lang.ArithmeticException的異常。
異常發(fā)生的原因有很多,通常包含以下幾大類:
•用戶輸入了非法數(shù)據(jù)。
•要打開的文件不存在。
•網(wǎng)絡(luò)通信時(shí)連接中斷,或者JVM內(nèi)存溢出。
這些異常有的是因?yàn)橛脩翦e(cuò)誤引起,有的是程序錯(cuò)誤引起的,還有其它一些是因?yàn)槲锢礤e(cuò)誤引起的。-
在Java語言中,異常從使用方式上可以分為兩大類:
在Java中類的異常結(jié)構(gòu)圖如下:
在異常處理時(shí)的幾點(diǎn)建議:
1永遠(yuǎn)不要catch中吞掉異常,否則在系統(tǒng)發(fā)生錯(cuò)誤時(shí),你永遠(yuǎn)不知道到底發(fā)生了什么
catch (SomeException e) { return null; }
2盡量使用特定的異常而不是一律使用Exception這樣太泛泛的異常
public void foo() throws Exception { //錯(cuò)誤的做法}
public void foo() throws MyBusinessException1, MyBusinessException2 { //正確的做法}
一味的使用Exception,這樣就違背了可檢查異常的設(shè)計(jì)初衷,因?yàn)檎{(diào)用都不知道Exception到底是什么,也不知道該如何處理。捕獲異常時(shí),也不要捕獲范圍太大,例如捕獲Exception,相反,只捕獲你能處理的異常,應(yīng)該處理的異常。即然方法的聲明者在方法上聲明了不同類型的可檢查異常,他是希望調(diào)用者區(qū)別對(duì)待不同異常的。
3Never catch Throwable class
永遠(yuǎn)不要捕獲Throwable,因?yàn)镋rror也是繼承自它,Error是Jvm都處理不了的錯(cuò)誤,你能處理?所以基于有些Jvm在Error時(shí)就不會(huì)讓你catch住。
4正確的封裝和傳遞異常
不要丟失異常棧,因?yàn)楫惓?duì)于定位原始錯(cuò)誤很關(guān)鍵
catch (SomeException e) { throw new MyServiceException("Some information: " + e.getMessage()); //錯(cuò)誤的做法 }
一定要保留原始的異常:
catch (SomeException e) { throw new MyServiceException("Some information: " , e); //正確的打開方式 }
5要打印異常,就不要拋出,不要兩者都做
catch (SomeException e) { LOGGER.error("Some information", e); throw e; }
這樣的log沒有任何意義,只會(huì)打印出一連串的error log,對(duì)于定位問題無濟(jì)于事。
6不要在finally塊中拋出異常
如果在finally中拋出異常,將會(huì)覆蓋原始的異常,如果finally中真的可能會(huì)發(fā)生異常,那一定要處理并記錄它,不要向上拋。
7不要使用printStackTrace
要給異常添加上有用的上下文信息,單純的異常棧,沒有太大意義
8Throw early catch late
異常界著名的原則,錯(cuò)誤發(fā)生時(shí)及早拋出,然后在獲得所以全部信息時(shí)再捕獲處理.也可以理解為在低層次拋出的異常,在足夠高的抽象層面才能更好的理解異常,然后捕獲處理。
9對(duì)于使用一些重量級(jí)資源的操作,發(fā)生異常時(shí),一定記得清理
如網(wǎng)絡(luò)連接,數(shù)據(jù)庫操作等,可以用try finally來做clean up的工作。
10不要使用異常來控制程序邏輯流程
我們總是不經(jīng)意間這么做了,這樣使得代碼變更丑陋,使得正常業(yè)務(wù)邏輯和錯(cuò)誤處理混淆不清;而且也可能會(huì)帶來性能問題,因?yàn)楫惓J莻€(gè)比較重的操作。
11及早校驗(yàn)用戶的輸入
在最邊緣的入口校驗(yàn)用戶的輸入,這樣使得我們不用再更底層邏輯中處處校驗(yàn)參數(shù)的合法性,能大大簡(jiǎn)化業(yè)務(wù)邏輯中不必要的異常處理邏輯;相反,在業(yè)務(wù)中不如果擔(dān)心參數(shù)的合法性,則應(yīng)該使用衛(wèi)語句拋出運(yùn)行時(shí)異常,一步步把對(duì)參數(shù)錯(cuò)誤的處理推到系統(tǒng)的邊緣,保持系統(tǒng)內(nèi)部的清潔。
12在打印錯(cuò)誤的log中盡量在一行中包含盡可能多的上下文
LOGGER.debug("enter A"); LOGGER.debug("enter B"); //錯(cuò)誤的方式
LOGGER.debug("enter A, enter B");//正確的方式
Thanks all. Happy Learning!!
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。