異常處理遇到過(guò)的那些坑 | 架構(gòu)棧

今年有個(gè)目標(biāo)之一就是提升團(tuán)隊(duì)代碼的質(zhì)量,所以時(shí)常會(huì)思索如何把這件事做到更好,不想教條主義,也不想搞出一個(gè)代碼規(guī)范,強(qiáng)制團(tuán)隊(duì)照著做,落地的效果不好,反而把大家的積極性給弄沒(méi)了。所以我的原則是,我們一起看看什么事是我們不能做的,排除掉,剩下的就是我們可以做的,同時(shí)真正搞清楚問(wèn)題在哪里,而不是簡(jiǎn)單的模仿。從我個(gè)人的經(jīng)驗(yàn)看,代碼優(yōu)化中最重要的一點(diǎn)就是對(duì)異常情況的處理。今天,我就借這個(gè)話(huà)題,談?wù)勅绾蝸?lái)優(yōu)化我們的代碼。

坑1:捕捉異常不做處理

如下段代碼所示,不知道各位在自家的代碼中見(jiàn)過(guò)多少,我是期望大家不要遇見(jiàn)。且不說(shuō)printStackTrace()這樣的代碼就不應(yīng)該出線(xiàn)在正式的上線(xiàn)代碼中,不做處理本身這會(huì)導(dǎo)致業(yè)務(wù)的潛在問(wèn)題被隱藏了,所以這個(gè)坑是我認(rèn)為異常處理中最糟糕的一點(diǎn)。

try

{

....

}

catch(Exception ex)

{

ex.printStackTrace();

System.out.println(XXX);

}

對(duì)于異常的捕捉處理,遵循以下的流程:

處理該異常,執(zhí)行具體的邏輯處理,加上必要的系統(tǒng)日志記錄 (log4j,logcat ...)。

涉及其他系統(tǒng)或者上一級(jí)系統(tǒng),需要轉(zhuǎn)換成對(duì)應(yīng)的消息通知相關(guān)系統(tǒng)。上一級(jí)是前端,需要轉(zhuǎn)換成前端可以“讀懂”的錯(cuò)誤提示。

無(wú)法處理該異?;蛘咴摦惓P枰弦患?jí)統(tǒng)一處理,Throw out該異常。

坑2:不處理資源釋放

還是見(jiàn)代碼說(shuō)話(huà),如果append出錯(cuò),那么IO流就不會(huì)被關(guān)掉,那么最終就會(huì)導(dǎo)致整個(gè)程序因?yàn)橐绯霰赖簟?/p>

FileWriter fileWriter = null;

try

{

fileWriter = new FileWriter("");

fileWriter.append(item.toString());

fileWriter.close();

}

catch (IOException e)

{

...

}

在使用文件、IO流、數(shù)據(jù)庫(kù)連接等不會(huì)自動(dòng)釋放的資源時(shí),應(yīng)該在使用完畢后馬上將其關(guān)閉。關(guān)閉資源的代碼try...catch...finally的finally內(nèi)執(zhí)行,否則就可能因?yàn)镋xception的原因造成資源無(wú)法釋放。

坑3:對(duì)異常不進(jìn)行分類(lèi)處理

代碼中,最容易看到的一種情況就是設(shè)定catch的異常類(lèi)型是Exception, 并且只有一套處理邏輯, 如下:

try{

...

}

catch (Exception e){

...

}

這里的問(wèn)題主要有以下兩點(diǎn):

1. catch的不同Exception,可能需要執(zhí)行不同的處理邏輯,一個(gè)catch要同時(shí)處理所有邏輯就很難實(shí)現(xiàn)。

2.?由于是捕捉的基類(lèi)Exception, 那么RuntimeException也會(huì)被捕捉到,如果稍微不注意的話(huà),RuntimeException最終沒(méi)有任何實(shí)際處理,代碼中的真正錯(cuò)誤被掩蓋掉了。

所以,正確的做法應(yīng)該是按照具體的異常進(jìn)行分類(lèi)處理, ?例如:

try{

...

}

catch (FileNotFoundException e){

// alert that the specified file

// does not exist

}

catch (EOFException e){

// alert that the end of the file

// was reached

}

catch (ObjectStreamException e){

// alert that the file is corrupted

}

catch (IOException e){

// alert that some other I/O

// error occurred

}

坑4:將大段代碼放進(jìn)一個(gè)Try-Catch中

有時(shí)可以看到,一些代碼的作者恨不得把整個(gè)函數(shù)里的實(shí)現(xiàn)代碼都放入單個(gè)try中,原因就在于為了圖省事,不愿花時(shí)間分析一大塊代碼中哪幾行代碼會(huì)拋出什么異常、異常的具體類(lèi)型是什么,應(yīng)該如何處理。這樣的做法導(dǎo)致異常發(fā)生后,后續(xù)調(diào)試找問(wèn)題更麻煩,一大段代碼中有太多的地方可能拋出Exception。這樣的做法導(dǎo)致,很難去統(tǒng)計(jì)和判斷要catch哪一些類(lèi)型的Exception, 只能寫(xiě)一個(gè)粗糙的Exception, ?又掉進(jìn)我們說(shuō)的第3個(gè)坑里。

一點(diǎn)總結(jié)

在和大家一起分析了上面的異常坑后,如果未來(lái)我們想避免踩進(jìn)一個(gè)異???,編寫(xiě)異常代碼可以遵循以下三個(gè)點(diǎn):

1. 出了什么錯(cuò)?

2. 在哪出的錯(cuò)?

3. 為什么出錯(cuò)?

更多文章,請(qǐng)手動(dòng)搜索微信公眾號(hào)【架構(gòu)?!浚?ForestNotes

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,734評(píng)論 18 399
  • 這篇文章主要是對(duì)Java異常選擇和使用中的一些誤區(qū)的總結(jié)和歸納,希望各位讀者能夠熟練掌握異常處理的一些注意點(diǎn)和原則...
    唐老鴨z閱讀 446評(píng)論 0 0
  • 芮城縣志》商賈篇:1853年,當(dāng)?shù)刎?cái)主錢(qián)太少在洛陽(yáng)做生意,商海30余年,積錢(qián)帛10000兩,老來(lái)攜一家老少20多口...
    籍秋風(fēng)閱讀 339評(píng)論 0 0
  • 想必您一看到標(biāo)題,腦子里就會(huì)想到是個(gè)小女孩在公園里手拿鮮花向一對(duì)對(duì)戀人叫賣(mài)的場(chǎng)景吧! 可今天講的卻是我本人的親身...
    為塵閱讀 697評(píng)論 7 5

友情鏈接更多精彩內(nèi)容