歡迎光臨
每天分享高質量文章

讓異常處理代碼更健壯

(給ImportNew加星標,提高Java技能)

來自:唐尤華

dzone.com/articles/good-exception-handling

像冠軍一樣處理異常。

哦,請不要這樣寫……

// 寫一句註釋跳過異常
try {
    throw new IOException("Made up");
} catch (IOException e) {
    // 跳過
}
// 記到日誌里,繼續處理
try {
    throw new IOException("Made up");
} catch (IOException e) {
    log.error("blah blah blah", e);
}
// 標記 TODO,不做任何處理
try {
    throw new IOException("Made up");
} catch (IOException e) {
    // TODO - 處理異常 (;
}

我在各種專案中發現了這種 catch 陳述句。這是一種“好辦法”,可以在短期內掩蓋問題。然而幾周或幾個月後,這些代碼將成為開發人員的噩夢。 絕大多數人可不想讀日誌查問題。 因此,還是讓我們避免這種情況。

規則一:catch 陳述句是用來處理異常的,把異常記到日誌里然後繼續執行不算處理。唯一的例外是,在發生異常後關閉資源(本文不討論這種情況;如果感興趣,可以參考這篇 McDowell 的博客,雖然寫的時間比較早,但內容很不錯)。

有三種處理異常的基本樣式:轉換(translate)重試(retry)恢復(recover)

轉換經常用於處理受檢異常(checked exception),在方法中異常無法丟擲,並且無法恢復時使用。 在這種情況下,將其轉換為運行時異常(runtime exception)而後丟擲是最合適的做法。接下來,運行時異常通常由框架處理。 在處理不可靠的服務時,重試非常有用,前提是重新嘗試有意義。一個很好的例子就是網絡中斷重試。如果定義了這種策略,那麼就能夠恢復到正常狀態。例如,如果通過網絡發送資料失敗,可以將資料寫入本地儲存。當然,這時就必須定義如何處理該檔案。

此外,上面提到的樣式可以組合,比如像下麵這個例子如下。

// 轉換
try {
    throw new IOException("Made up");
} catch (IOException e) {
    throw new RuntimeException(e);
}
// 重試5次後放棄
boolean end = false;
int count = 0;
while (end == false) {
    try {
        // 發送信息
        if (true) {
            throw new MessagingException("Made up");
        }
        end = true;
    } catch (MessagingException e) {
        if (count >= 5) {
            // 嘗試5次放棄。
            throw new RuntimeException("was not able to send message even after five tries", e);
        }
        ++count;
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e1);
        }
    }
}
// 恢復:如果傳輸失敗記錄到檔案
try {
    // 發送信息
    throw new MessagingException("Made up");
} catch (MessagingException e) {
    try {
        // 寫檔案
        throw new IOException("Made up");
    } catch (IOException e1) {
        // 如果寫檔案失敗,不再進行恢復
        throw new RuntimeException(e1);
    }
}

 

如果一切都失敗了,那麼上面這種方法至少可以確保你能意識到問題所在。 此外,它還提供了問題的真正原因,從而讓你能快速定位問題。

 

祝編程快樂!

    赞(0)

    分享創造快樂