2014-02-10 43 views
2

我正在閱讀其他人編寫的代碼。未經檢查的異常和已檢查的異常都是自定義異常。我看到一個未經檢查的異常在方法內被拋出,並且被包裝到catch子句中的檢查異常中並再次拋出。將未檢查的異常包裝到檢查的異常中是一種常見做法?如果是的話,我們爲什麼要這樣做?將未經檢查的異常包裝到Java中的已檢查異常中

+0

我能想到的一個原因是,如果你不想自己處理異常,但是你想強制調用者處理它。但我可能是錯的。 –

回答

3

自unchecked異常是"leaky abstractions."

應用程序罪魁禍首可能定義一個接口,它依賴於服務。如果實現拋出特定於應用程序想要處理的特定於實現的未檢查異常,它將受到特定於實現的異常類型的污染。如果替換實施,則會導致維護頭痛。

爲避免此問題,可以將未檢查的異常封裝在由接口定義的與實現無關的已檢查異常中。

作爲一個具體的例子,考慮Hibernate使用未經檢查的異常來通知調用者違反約束。假設您有一個User實體,並且用戶名在數據庫中定義了唯一約束。您希望通過提示用戶輸入不同的名稱來專門處理此情況。如果Hibernate的ConstraintViolationException在堆棧上保持不變,應用程序將需要Hibernate特定的處理程序。另一方面,如果數據訪問層將其包含在合適的自定義檢查異常中,則用新的ORM實現替換Hibernate將不需要超出實現層的任何更改。

+0

這對我的一般問題來說是一個很好的答案。謝謝。我想給你更多的細節。在服務委託類中,它引發一個未經檢查的異常,調用此委託的方法將它重新引發爲檢查異常。未檢查和已檢查的異常都是應用程序定義的自定義異常。這是一個好習慣嗎? – user3123690

+0

服務委託類中的方法正在幾個地方被調用。因此,委託類中拋出的未經檢查的異常在某些地方被忽略,並且在某些地方作爲檢查異常被重新拋出。所以,我對這種用法感到困惑。 – user3123690

+1

它可能沒關係。也就是說,做包裝的調用者(在某些情況下)可能有一些上下文來區分未檢查和已檢查的異常。經驗法則是,未經檢查的異常應該是調用者編程錯誤的結果,而不是環境問題或數據驅動的問題。如果這些自定義的未經檢查的例外不符合該標準,我會更加懷疑。 – erickson

1

如果你這樣做的方法meth很可能是因爲代碼調用
meth將只需要瞭解並檢查檢查異常。
說,如果meth可以拋出5種不同類型unchecked異常,
你做這個更加均勻,並允許調用代碼只
擔心檢查之一。但是,當然你也可以使用未經檢查的異常
。只是編譯器不能在調用代碼中幫助你。

+0

謝謝你的回覆,彼得。你從不同的角度回答了它。我假設我只能選擇一個作爲答案。我不太瞭解論壇的規則。 – user3123690

+0

沒問題。你選擇你最喜歡的那個:)祝你好運。 –