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