Java 異常處理基本規則,Java異常處理的基本規範

看了團隊中原來代碼中的異常處理,心碎了一地,稍微對照阿里巴巴的異常處理規範整理了一遍,準備分享一下,Java的異常處理規範&約束。程序員

1、運行異常的撲捉

不要捕獲 Java 類庫中定義的繼承自 RuntimeException 的運行時異常類,如:IndexOutOfBoundsException / NullPointerException ,這類異常由程序員預檢查來規避,保證程序健壯性。數據庫

正例:bash

if(null != obj) {
    //TODO
}
複製代碼

反例:ui

try {
    obj.method()
} catch(NullPointerException e){
   //TODO
}
複製代碼

2、 try-catch 做用域(現有代碼出現率較高)

對大段代碼進行try-catch ,這是不負責任的表現。catch 時請分清穩定代碼和非穩定代碼,穩定代碼指的是不管如何不會出錯的代碼。對於非穩定代碼的 catch 儘量進行區分異常類型,再作對應的異常處理。url

正例: 分塊catch ,或者直接拋出相對應的異常,而後由下層細化處理。spa

map.put("status", 500);   
try{
    //代碼省略
    map.put("message", "success!");   
    map.put("status", 200);   
} catch (UnknownHostException e) {
    //域名錯誤
    map.put("message", "請輸入正確的網址");
    LoggerUtils.fmtError(e, "網址異常[%s]", url);
} catch (SocketTimeoutException e) {
    //超時
    map.put("message", "請求地址超時");
    LoggerUtils.fmtError(e, "請求地址超時[%s]", url);
 
} catch (Exception e) {
    //其餘異常
    map.put("message", "請求出現未知異常,請重試!\r\n" + e.getMessage());
    LoggerUtils.fmtError(e, "請求出現未知異常,請重試![%s]", url);
}
return map;
複製代碼

反例:code

try {
   //此處省略1024行代碼
} catch(Exception e){
   //TODO
}
複製代碼

3、異常的捕捉 & 異常的處理(現有代碼出現率較高)

捕獲異常是爲了處理它,不要捕獲了卻什麼都不處理而拋棄之,若是不想處理它,請將該異常拋給它的調用者。最外層的業務使用者,必須處理異常,將其轉化爲用戶能夠理解的內容。cdn

正例:對象

try{
    //代碼省略
} catch (UnknownHostException e) {
    //域名錯誤
    map.put("message", "請輸入正確的網址");
    LoggerUtils.fmtError(XXXXManager.class, e, "網址異常[%s]", url);
} catch (SocketTimeoutException e) {
    //超時
    map.put("message", "請求地址超時");
    LoggerUtils.fmtError(XXXXManager.class, e, "請求地址超時[%s]", url);
 
} catch (Exception e) {
    //其餘異常
    map.put("message", "請求出現未知異常,請重試!\r\n" + e.getMessage());
    LoggerUtils.fmtError(XXXXManager.class, e, "請求出現未知異常,請重試![%s]", url);
}
複製代碼

只爲描述一下異常,繼續拋出。繼承

try{
    //代碼省略
} catch (UnknownHostException e) {
    throw new HNException("xxx處理失敗。",e);
}
複製代碼

反例: 1.以下,調用者對異常沒有任何感知。

try{
    //代碼省略
} catch (Exception e) {
    System.out.println("插入異常");
}
複製代碼

2.以下,調用者對異常沒法定位和判斷

try{
    //代碼省略
} catch (UnknownHostException e) {
    throw new RuntimeException("500");
}
複製代碼

4、異常 & 事務

  1. try 塊放到了事務代碼中,catch 異常後,若是須要回滾事務,必定要注意手動回滾事務。
  2. 在有事務的代碼中,catch 異常後,作描述異常等處理後,若是須要事務生效,請把異常繼續拋出。

5、異常 & finally

1.若是有對IO 流和資源作操做,必須逐一關閉IO 流和資源對象(從裏層到外層),有異常也要作處理。

try{
    //代碼省略
} catch (Exception e) {
    throw new HNException("xxx處理失敗。",e);
 
}finally{
             
    try {
        if(null != conn){
            conn.disconnect();
        }
    } catch (Exception e1) {
        LoggerUtils.fmtInfo("請求完畢關閉流出現異常![%s]", url);
    }
    try {
        if(null != outStream){
            outStream.close();
        }
    } catch (Exception e2) {
        LoggerUtils.fmtInfo("請求完畢關閉流出現異常![%s]", url);
    }
    try {
        if(null != out){
            out.close();
        }
    } catch (Exception e3) {
        LoggerUtils.fmtInfo("請求完畢關閉流出現異常![%s]", url);
    }
             
}
複製代碼

JDK 7 以上可使用try-with-resources 方式。

6、finally & return

不能在 finally 塊中使用 returnfinally 塊中的 return 返回後方法結束執行,不會再執行 try 塊中的 return 語句。

7、異常須要精確

捕獲異常與拋異常,必須是徹底匹配,或者捕獲異常是拋異常的父類。若是預期對方拋的是繡球,實際接到的是鉛球,就會產生意外狀況。

8、程序員的基本修養 & NPE(現有代碼中出現率較高)

1.方法(接口)的返回值能夠爲 null ,但不推薦返回空集合,或者空對象等,必須添加註釋充分說明什麼狀況下會返回 null 值。調用方須要進行 null 判斷防止 NPE 問題。

  1. 防止 NPE ,是程序員的基本修養,注意 NPE 產生的場景。

    a.查詢數據庫返回null ,包括null 對象和null 集合。

    b.集合內元素有null 對象。

相關文章
相關標籤/搜索