2010-07-28 18 views
3

看到API中的檢查期望並不罕見,其中最着名的示例之一是IOExceptionCloseable.close()。經常處理這個異常真的讓我很煩惱。更令人討厭的例子是我們的一個項目。它由多個組件組成,每個組件聲明特定的檢查異常。這個問題(在我看來)是,在設計時它並不完全知道某些例外會是什麼。因此,例如,組件Configurator宣稱爲ConfiguratorExeption。當我問爲什麼不只是使用未檢查的異常時,我被告知我們希望我們的應用程序是健壯的,不會在運行時造成衝擊。但它是一個弱論據,因爲:在外部API中使用檢查的異常是個好主意?

  1. 大多數這些例外有效地使應用程序無法使用。是的,它不會炸燬,但它不能使任何東西泄漏與消息日誌。
  2. 這些例外情況並不具體,並且實際上意味着「發生了不良事件」。客戶應該如何恢復?
  3. 事實上,所有恢復都由日誌記錄異常組成,然後吞下它。這在大型try-catch聲明中執行。

我想,這是一個反覆出現的模式。但是仍然檢查異常在API中被廣泛使用。這是什麼原因?是否有某些類型的API更適合於檢查異常?

回答

2

圍繞這個問題已經有很多controversy

看看這個關於這個問題http://www.mindview.net/Etc/Discussions/CheckedExceptions

我個人傾向於使用Runtime例外自己,已經開始考慮使用checked異常的API中一個壞主意的經典文章。

其實一些非常流行的Java API的也開始做同樣的,例如,休眠放棄了使用checked異常的運行系統由3版,框架也贊成使用運行時的過檢查的異常。

2

檢查異常應只針對事情是1)特殊拋出他們是一個例外,成功的法則,最可憐的異常拋出是防禦性的編碼2)可怕的習慣客戶端可操作。如果發生了某種情況,API的客戶端無法以任何方式影響其運行時異常。

+0

但是,例如,我懷疑close()上的'IOException'是客戶端可以操作的_always_。根據我的經驗,這往往是不可行的。 – Rorick 2010-07-28 21:02:24

+0

你讓我的觀點是,這是Sun API的問題,而不是我的建議:-) – 2010-07-29 05:14:18

2

大型庫的一個問題是,它們沒有記錄可能拋出的所有異常,所以如果沒有記錄的RuntimeException恰好從深層代碼中拋出,那麼代碼可能隨時會彈出「擁有」。

通過明確聲明所有這些,至少使用該庫的開發人員有編譯器幫助正確處理它們。

沒有什麼能夠在早上3點進行法醫分析,發現某些情況引發了這種未申報的例外情況。

+0

這是運行時異常的問題,您完全依賴所有記錄的異常。是的,當一些未公開的運行時異常深入代碼中時,這是一件很痛苦的事情。這些類型的例外可能難以測試。最糟糕的情況是它在部署後突然彈出。 – 2010-07-29 01:00:03

+1

這就是單元測試的目的,不僅僅是成功的場景,還有失敗的場景 – 2010-07-29 05:15:29

+0

@fuzzy,你從未遇到過在開發過程中沒有發生過的生產情況? – 2010-07-29 08:17:48

1

有對此事的不同看法,但我傾向於把事情如下:

  • 一個檢查異常代表了一個可以合理預期下,一些可預見的,特殊情況仍在發生的事件「在程序/典型呼叫者的正常操作條件下」,並且通常可以在呼叫堆棧上處理得不太遠;
  • 未經檢查的異常表示我們在程序的正常運行環境中「不會真正期望發生」並且可以在相當高的調用堆棧上處理的條件(或者可能導致我們在更簡單的應用程序中關閉應用程序);
  • en 錯誤表示如果發生這種情況,我們通常會期望導致我們關閉應用程序。

例如,它在典型環境的範圍內,在某些例外情況下(但相當可預測),關閉文件可能會導致I/O錯誤(在關閉時將緩衝區刷新到文件當磁盤已滿時)。所以決定讓Closable拋出檢查的IOException可能是合理的。

另一方面,在標準Java API中有一些例子,其中的決定不太可靠。當涉及到檢查異常(爲什麼沒有找到一個你真正希望在一個典型的應用程序中發生和處理的XML解析器......?)時,我會說XML API通常是overfussy,就像反射API(你通常真的希望找到類的定義,不管它們是不是......)。但許多決定都是有爭議的。

一般來說,我會同意「配置異常」類型的異常可能不被檢查。

請記住,如果您調用的方法聲明瞭一個檢查的異常,但是「如果拋出它真的不會指望它被拋出,真的不知道該怎麼做」,那麼你可以通過編程方式「聳聳肩你的肩膀「並將其重新轉換爲RuntimeException或Error ...

0

實際上,您可以使用Exception tunneling,以便泛型異常(例如ConfiguratorException)可以提供有關出錯的更多詳細信息(例如一個FileNotFound)。

一般來說,我會告誡這個然而,因爲這很可能是一個leaky abstraction(應該沒有人關心你的配置是否正試圖從文件系統,數據庫中提取其數據,通過網絡或其他)

如果你正在使用檢查的例外,那麼至少你會知道你的抽象是在哪裏和爲什麼泄漏。恕我直言,這是一件好事。

相關問題