這是更好的實踐問題。Java中的子類異常:何時不是自定義消息「足夠好」?
我正在使用舊的Java代碼。我看到很多Exception的子類只覆蓋構造函數。我不確定是否有像這樣的子類異常的實際用法。我認爲只是調用Exception構造函數並傳遞消息就會有效,並且不會有很多子類。代碼是責任。
這是更好的實踐問題。Java中的子類異常:何時不是自定義消息「足夠好」?
我正在使用舊的Java代碼。我看到很多Exception的子類只覆蓋構造函數。我不確定是否有像這樣的子類異常的實際用法。我認爲只是調用Exception構造函數並傳遞消息就會有效,並且不會有很多子類。代碼是責任。
子類化的要點是您的代碼可以區分不同類型的故障並將它們區別對待。如果您只是更改該消息,那麼人可以在日誌中區分它們,但僅此而已。
如果您看到的異常實際上處理方式不同,但只是陷入了一個全面的catch(Exception e)
,那麼可能有人對子類過於熱衷,但它通常用於清晰地分離代碼層和工作哪些類應該處理哪些類型的問題。
例如,一種類型的異常可能表示超時,並且可能適合在短暫延遲後重試,而另一種類型的異常表示不可恢復的失敗(可能是無效查詢),必須將其拋出更高級別或可能向用戶指示。
當你有一個子類時,你可以捕獲它。您不能有選擇地根據其消息捕捉異常。
子類是更具描述性的和更容易使用:
throw new Exception("User does not exist " + userName);
相比:
throw new UserNotExistsException(userName);
也後者異常可以具有getUserName()
方法和字段相應地捕獲時,以提取重要信息。你不想解析異常信息,不是嗎?
子類化是要走的路。稍後在應用程序的生命週期中,您可能需要更改異常消息。誰知道它可能會顯示在頁面上,並且需要調整措辭。
將錯誤消息包裝在自己的Exception子類中有助於維護乾淨的代碼並輕鬆地針對給定的錯誤類別進行測試。
要添加到其他的答案:
如果擴展Exception
,並把它,你宣佈一個新的檢查異常。它必須在方法的throws子句中聲明。您對來電者說:「這是您必須編碼的不尋常的情況。」
我認爲檢查的異常是過度使用的。在呼叫者可以期望從問題中恢復的情況下,它們只是非常有用。我所看到的絕大多數例外都是調用方無法合理期望從中恢復的那種。在這種情況下,您應該使用RuntimeException
後代,如IllegalStateException
或IllegalArgumentException
,並讓頂層錯誤處理負責處理它。
這樣做的目的是爲了更清晰和更精確地捕捉異常。如果所有的代碼只是拋出Exception
,你的異常處理代碼將看起來像這樣:
try {
// ...
throw new Exception("configuration error");
// ...
throw new Exception("missing value error");
// etc.
} catch (Exception e) {
// do something
}
這將是尷尬在至少處理不同類型的錯誤的方式不同。更重要的是,這段代碼將吞噬所有的異常,即使你沒有預料到的異常,也沒有編寫特定的錯誤處理邏輯。在另一方面,如果你寫
try {
// ...
throw new ConfigurationException();
// ...
throw new MissingValueException();
// etc.
} catch (ConfigurationException e) {
System.err.println("error: bad configuration");
System.exit(1);
} catch (MissingValueException e) {
return DEFAULT_VALUE;
}
你就可以輕鬆地和清潔處理不同類型的錯誤,而不必擔心你的錯誤處理代碼將在你沒來的情況下運行預計它不會。
+1對於過度熱心的開發者。 – 2012-02-20 18:34:48