2011-10-31 123 views
12

當通常足以處理方法中的大多數條件失敗時,爲什麼不鼓勵拋出通用(java.lang.Exception)異常?我知道如果一個方法可以拋出多種類型的異常,那麼拋出一個異常的特定子類可能會澄清一點處理,但在一般的失敗/成功案例中,我認爲異常服務已經足夠。投擲泛型異常不鼓勵?

+0

[Java或C#中異常管理的最佳實踐]的可能重複(http://stackoverflow.com/questions/409563/best-practices-for-exception-management-in-java-or-c-sharp) –

回答

20

的問題是,Exception也是RuntimeException超類,其中包括了一些東西,不應該被抓住,因爲它表明與編程問題,而不是一個特殊的條件是由上下文產生的。在正常情況下,您不想捕獲BufferOverflowException或UnsupportedOperationException。此外,拋出單獨的異常類型給調用代碼控制如何處理每一個。新的多捕獲功能在Java 7中減少了鍋板數量。

+1

這是另一個重要問題,+1。 –

+0

@MarkPeters雖然我很少說「從不」,因爲我認爲即使是最糟糕的反模式在扭曲的情況下也是正確的答案,所以最好小心一些例外情況。有時候他們必須通過你沒有寫的代碼來處理,最終會在整個商店泄漏抽象。那麼,當然,還有那些追上'Throwable'就好像沒什麼大不了的:D –

+0

+1 - 確實非常好。 – DerMike

5

如果拋出更具體的例外情況,則不會阻止任何調用代碼在一個Exception catch塊中處理所有這些異常。更具體的是更多地記錄發生了什麼類型的錯誤,使程序員更容易分開處理它們。

此外,通過拋出「異常」本身,你基本上告訴你的代碼的調用者,他們不能排除任何類的異常。一個IOException可能發生,因爲可能在NumberFormatException

1

通常你想知道你的應用程序發生了什麼,只有在你沒有明確定位的異常時,纔會捕獲特定的異常並讓程序失敗(或者按照執行順序更高)。 捕捉異常會捕捉到它們,在某些情況下,您不知道程序失敗。

3

一如既往:這取決於。

我認爲你暴露給別人的API是有區別的。這可能會活一段時間。在這種情況下,你不知道主叫方認爲他的情況最好。

另一方面,總是有你自己內部使用的代碼。拋出一個通用的異常可能就足夠了。但請記住,您可能稍後要更改一些異常處理。當所有的錯誤情況一起發生時,這將會更加困難。

0

Dittos to GH。我會使用「空指針異常」和「內存不足異常」作爲更明顯的例子,您可能不會注意到與真正的應用程序例外在同一個塊中捕獲的異常。

我還想補充一點,爲未來的可擴展性付出一點努力是值得的。如果你在所有地方拋出泛型異常,並且後來你決定需要捕獲一些異常而不是其他異常,那麼返回並改變它們可能是一個主要的痛苦。但是,如果你只是在創建你需要的例外時,這並不是什麼大不了的事情。創建一個只接受帶消息構造函數的新異常類需要5行代碼?這對未來是很好的投資。

像編程中的許多事情一樣,這是一個你走多遠的問題。我通常在我工作的幾乎每個項目中都會創建一個相當通用的「BadInputException」,並且在用戶輸入失敗驗證條件時隨時拋出此錯誤。然後,我可以捕獲BadInputException並將消息扔到屏幕上。如果我創建了一個爲不一致數據拋出異常的複雜類,那麼我通常會爲它創建一個異常類。就像我創建一個「TalkToDatabase」類,我將創建一個「TalkToDatabaseException」。 (也許不止如此,如果有多種例外,我知道我想抓住,但至少是一個。)

順便說一句,我不知道你是否想到這一點,但我強烈勸阻檢查錯誤消息的文本以確定錯誤的類型。我見過他們拋出通用例外所有的地方節目,然後在catch塊他們有這樣的代碼

// Very bad idea! Don't do this! 
catch (Exception ex) 
{ 
    if (ex.getMessage().equals("Invalid foo")) 
    ... handle bad foo ... 
    else if (ex.getMessage().equals("Plugh is over maximum")) 
    ... handle bad plugh ... 
    ... etc ... 
} 

這將是更好的,只是讓這些情況單獨例外。處理不僅會更有效率,而且假設你做了以上的事情,稍後有人出現並決定將消息更改爲「Foo無效」?該程序仍然會編譯,但不能正常工作。