誤區(qū)四、忽略異常
如下異常處理只是將異常輸出到控制臺(tái),沒(méi)有任何意義。而且這里出現(xiàn)了異常并沒(méi)有中斷程序,進(jìn)而調(diào)用代碼繼續(xù)執(zhí)行,導(dǎo)致更多的異常。
清單 4
public void retrieveObjectById(Long id){
try{
//。.some code that throws SQLException
}catch(SQLException ex){
/**
*了解的人都知道,這里的異常打印毫無(wú)意義,僅僅是將錯(cuò)誤堆棧輸出到控制臺(tái)。
* 而在 Production 環(huán)境中,需要將錯(cuò)誤堆棧輸出到日志。
* 而且這里 catch 處理之后程序繼續(xù)執(zhí)行,會(huì)導(dǎo)致進(jìn)一步的問(wèn)題*/
ex.printStacktrace();
}
}
可以重構(gòu)成:
清單 5
public void retrieveObjectById(Long id){
try{
//。.some code that throws SQLException
}
catch(SQLException ex){
throw new RuntimeException(“Exception in retieveObjectById”, ex);
}
finally{
//clean up resultset, statement, connection etc
}
}
這個(gè)誤區(qū)比較基本,一般情況下都不會(huì)犯此低級(jí)錯(cuò)誤J。
誤區(qū)五、將異常包含在循環(huán)語(yǔ)句塊中
如下代碼所示,異常包含在 for 循環(huán)語(yǔ)句塊中。
清單 6
for(int i=0; i《100; i++){
try{
}catch(XXXException e){
//…。
}
}
我們都知道異常處理占用系統(tǒng)資源。一看,大家都認(rèn)為不會(huì)犯這樣的錯(cuò)誤。換個(gè)角度,類 A 中執(zhí)行了一段循環(huán),循環(huán)中調(diào)用了 B 類的方法,B 類中被調(diào)用的方法卻又包含 try-catch 這樣的語(yǔ)句塊。褪去類的層次結(jié)構(gòu),代碼和上面如出一轍。
誤區(qū)六、利用 Exception 捕捉所有潛在的異常
一段方法執(zhí)行過(guò)程中拋出了幾個(gè)不同類型的異常,為了代碼簡(jiǎn)潔,利用基類 Exception 捕捉所有潛在的異常,如下例所示:
清單 7
public void retrieveObjectById(Long id){
try{
//…拋出 IOException 的代碼調(diào)用
//…拋出 SQLException 的代碼調(diào)用
}catch(Exception e){
//這里利用基類 Exception 捕捉的所有潛在的異常,如果多個(gè)層次這樣捕捉,會(huì)丟失原始異常的有效信息
throw new RuntimeException(“Exception in retieveObjectById”, e);
}
}
可以重構(gòu)成
清單 8
public void retrieveObjectById(Long id){
try{
//。.some code that throws RuntimeException, IOException, SQLException
}catch(IOException e){
//僅僅捕捉 IOException
throw new RuntimeException(/*指定這里 IOException 對(duì)應(yīng)的錯(cuò)誤代碼*/code,“Exception in retieveObjectById”, e);
}catch(SQLException e){
//僅僅捕捉 SQLException
throw new RuntimeException(/*指定這里 SQLException 對(duì)應(yīng)的錯(cuò)誤代碼*/code,“Exception in retieveObjectById”, e);
}
}
評(píng)論
查看更多