處理Java異常的9個最佳實踐

原創於【模稜博客】 http://www.flammulina.com

Java中的異常處理不是一個簡單的主題。初學者發現很難理解,甚至有經驗的開發人員也可以花幾個小時討論如何以及應該拋出或處理哪些Java異常。

處理Java異常的9個最佳實踐

這就是為什麼大多數開發團隊都有自己的如何使用它們的規則。如果你是一個團隊的新手,你可能會驚訝於這些規則與你之前使用過的規則有多麼不同。

儘管如此,大多數團隊都使用了幾種最佳實踐。以下是幫助您入門或改進異常處理的9個最重要的內容。

處理Java異常的9個最佳實踐

1.清理Finally塊中的資源或使用Try-With-Resource語句

經常發生在try塊中使用資源,比如InputStream,之後需要關閉它。這些情況下的一個常見錯誤是在try塊結束時關閉資源。

處理Java異常的9個最佳實踐

問題是隻要沒有拋出異常,這種方法似乎完全正常。try塊中的所有語句都將被執行,資源將被關閉。

但是你添加了try塊是有原因的。您調用一個或多個可能引發異常的方法,或者您自己拋出異常。這意味著您可能無法到達try塊的末尾。因此,您不會關閉資源。

因此,您應該將所有清理代碼放入finally塊或使用try-with-resource語句。

使用Finally塊

與try塊的最後幾行相比,finally塊始終執行。這可以在成功執行try塊之後或在catch塊中處理異常之後發生。因此,您可以確保清理所有已打開的資源。

處理Java異常的9個最佳實踐

另一種選擇是try-with-resource語句,我在Java異常處理的介紹中對此進行了更詳細的解釋。

如果資源實現AutoCloseable接口,則可以使用它。這就是大多數Java標準資源所做的事情。當您在try子句中打開資源時,它將在try塊執行後自動關閉,或者處理異常。

處理Java異常的9個最佳實踐

2.首選特殊例外情況

拋出的異常越具體越好。請記住,不知道您的代碼的同事,或者您可能在幾個月內需要調用您的方法並處理異常。

因此,請務必儘可能多地提供信息。這使您的API更容易理解。因此,您的方法的調用者將能夠更好地處理異常或通過額外的檢查來避免它。

因此,總是嘗試找到最適合您的異常事件的類,例如拋出NumberFormatException而不是IllegalArgumentException。並避免拋出非特定的異常

處理Java異常的9個最佳實踐

3.記錄您指定的例外情況

只要在方法簽名中指定了異常,就應該在Javadoc中記錄它。這與以前的最佳實踐具有相同的目標:為調用者提供儘可能多的信息,以便他可以避免或處理異常。

因此,請確保向Javadoc 添加@throws聲明並描述可能導致異常的情況。

處理Java異常的9個最佳實踐

4.使用描述性消息拋出異常

這種最佳實踐背後的想法類似於前兩種實踐。但是這次,您不向調用方提供有關方法的信息。每個必須瞭解在日誌文件或監視工具中報告異常時發生的事情的人都會讀取該異常的消息。

因此,它應儘可能準確地描述問題,並提供最相關的信息來理解異常事件。

別誤會我的意思; 你不應該寫一段文字。但你應該用1-2個短句

來解釋異常的原因。這有助於您的運營團隊瞭解問題的嚴重性,還可以讓您更輕鬆地分析任何服務事件。

如果拋出一個特定的異常,它的類名很可能已經描述了那種錯誤。因此,您無需提供大量其他信息。一個很好的例子是NumberFormatException。當您以錯誤的格式提供String時,它會被類java.lang.Long的構造函數拋出。

處理Java異常的9個最佳實踐

NumberFormatException類的名稱已經告訴您問題的類型。它的消息只需要提供導致問題的輸入字符串。如果異常類的名稱不具有表現力,則需要在消息中提供所需的信息。

處理Java異常的9個最佳實踐

處理Java異常的9個最佳實踐

5.首先捕獲最具體的異常

大多數IDE都可以幫助您實現這一最佳實踐。當您嘗試首先捕獲不太具體的異常時,它們會報告無法訪問的代碼塊。

問題是隻有匹配異常的第一個catch塊才會被執行。因此,如果首先捕獲IllegalArgumentException,則永遠不會到達應該處理更具體的

NumberFormatException的catch塊,因為它是IllegalArgumentException的子類。

始終首先捕獲最具體的異常類,並將不太具體的catch塊添加到列表的末尾。

您可以在以下代碼段中看到此類try-catch語句的示例。第一catch塊處理所有NumberFormatException的 S和第二個所有拋出:IllegalArgumentException S的不是NumberFormatException異常

處理Java異常的9個最佳實踐

6.不要抓住Throwable

Throwable是所有異常和錯誤的超類。你可以在catch子句中使用它,但你永遠不應該這樣做!

如果在catch子句中使用Throwable,它不僅會捕獲所有異常; 它還會捕獲所有錯誤。JVM拋出錯誤以指示應用程序無意處理的嚴重問題。典型的例子是OutOfMemoryErrorStackOverflowError。兩者都是由應用程序無法控制的情況引起的,無法處理。

所以,最好不要抓住Throwable,除非你完全確定你處於一個特殊情況,你可以或者需要處理錯誤。

處理Java異常的9個最佳實踐

7.不要忽視例外

您是否曾經分析過只有用例的第一部分被執行的錯誤報告?

這通常是由一個被忽略的異常引起的。開發人員可能非常確定它永遠不會被拋出並添加了一個不處理或記錄它的catch塊。當你發現這個區塊時,你很可能甚至會發現一個著名的“這將永遠不會發生”的評論。

處理Java異常的9個最佳實踐

好吧,你可能正在分析一個不可能發生的問題。

所以,請永遠不要忽視異常。您不知道代碼將來會如何變化。有人可能會刪除阻止異常事件的驗證而不會認識到這會產生問題。或者拋出異常的代碼會被更改,現在拋出同一個類的多個異常,並且調用代碼不會阻止所有這些異常。

你至少應該寫一條日誌消息,告訴大家不可想象的事情剛剛發生,而且有人需要檢查它。

8.不要記錄並扔掉

這可能是此列表中最常被忽略的最佳做法。您可以找到許多代碼片段,甚至可以找到異常被捕獲,記錄和重新拋出的庫。

處理Java異常的9個最佳實踐

在發生異常時記錄異常可能會很直觀,然後重新拋出它以便調用者可以適當地處理它。但它會為同一個異常寫出多條錯誤消息。

處理Java異常的9個最佳實踐

其他消息也不會添加任何信息。如最佳實踐#4中所述,異常消息應描述異常事件。堆棧跟蹤告訴您拋出異常的類,方法和行。

如果需要添加其他信息,則應捕獲異常並將其包裝在自定義異常中。但請務必遵循最佳做法

處理Java異常的9個最佳實踐

因此,如果您想要處理它,只捕獲異常。否則,在方法簽名中指定它並讓調用者處理它。

9.在沒有消費的情況下包裝例外

有時候捕獲標準異常並將其包裝成自定義異常會更好。此類異常的典型示例是應用程序或框架特定的業務異常。這允許您添加其他信息,還可以為異常類實現特殊處理。

執行此操作時,請確保將原始異常設置為原因。該異常類提供了接受一個特定的構造方法的Throwable作為參數。否則,您將丟失原始異常的堆棧跟蹤和消息,這將導致難以分析導致異常的異常事件。

處理Java異常的9個最佳實踐

摘要

處理Java異常的9個最佳實踐

正如您所看到的,當您拋出或捕獲異常時,您應該考慮許多不同的事情。其中大多數都旨在提高代碼的可讀性或API的可用性。

例外通常是錯誤處理機制和通信媒介同時。因此,您應該確保討論要與同事一起應用的Java異常處理最佳實踐和規則,以便每個人都能理解一般概念並以相同的方式使用它們。

將Retrace APM與代碼分析一起使用時,您可以直接從Java 收集異常,而無需更改任何代碼!


分享到:


相關文章: