2009-12-02 55 views
5

假設我有一個MyException類,它的子類是Exception。當我的代碼中發生錯誤時,我正在使用這個類來包含上下文信息。可以在不拋出它的情況下實例化異常嗎?

我通常用它來包裝「標準」異常類之一。例如,如果輸入驗證過程中發生錯誤,我會做這樣的事情

if (invalidInput()) 
    throw new MyException(new IllegalArgumentException(), arg1, arg2, ...); 

但我的IDE(IntelliJ IDEA的)警告我說,不拋出它是壞的實例化一個未經檢查的異常(拋出:IllegalArgumentException在這個例子中),但不告訴我爲什麼。

那麼如何實例化一個異常而不拋出它有多罪?我會去哪個圈子?

+1

爲什麼不在這種情況下擴展IllegalArgumentException? – Zed 2009-12-02 11:05:14

+0

@Zed因爲我使用MyException來包裝幾乎所有可以在我的代碼中拋出的異常。 – lindelof 2009-12-02 11:06:37

+0

你讓自己擺脫了所有的信息,'catch'沒用...... blech。 ( – 2009-12-02 11:16:45

回答

8

你可能會更好拋出拋出IllegalArgumentException的一個實例,在這種情況下,這就是它是:

if (invalidInput()) 
     new IllegalArgumentException("Invalid argument " + x + ", expected ..."); 

或者以其他方式擴展,IllegalArgumentException而不是Exception,它如果你想用自定義屬性來增強它。

public class MyIllegalArgumentException extends IllegalArgumentException { 
    public MyIllegalArgumentException(Object arg...) { .... } 
} 

這兩種情況都提供了一個更精簡,更有意義的類模型。

更新: 給你關於希望與拋出的異常提供上下文信息的評論 - 通過提供您的自定義異常對象爲Throwable的參數標準的例外,你可以做到這一點構造器即翻轉輪這樣:代替在你的例外中包裝相關的標準例外,你應該把你的例外包裝在相關的標準例外中。

if (invalidInput()) 
     new IllegalArgumentException("Invalid argument " + x + ", expected ...", new MyContextException(a,b,c)); 

(其中a,b & c是要發送的上下文的各種比特)。 通過這種方式,您可以在代碼中的所有位置使用有意義的&適當的異常,但是您可以在處理/記錄異常時傳輸可能希望在堆棧中使用的上下文信息。

+0

@Zed - 剛剛看到你的評論想要包裝所有例外。請記住,如果你這樣做,你將會使異常處理變得更加困難,並且代碼的可讀性也會降低。我更新了一個可能更適合您的需求的備選建議。 – Joel 2009-12-02 11:24:24

2

你不會像你這樣做實例化異常。我確信警告在那裏確保您將異常用作例外而不僅僅是任何對象。

但是,你要下地獄有MyException不繼承RuntimeException的;)

2

這並不糟糕。

和大多數警告一樣,它們表示那些合法發生的可能性較小的情況,而不是被錯誤地引用的情況。另一個最近的例子是關於同步局部變量的警告;通常你不想這樣做,而且很容易通過無意間搞亂併發。

IntelliJ只是警告你,異常通常會立即被拋出,所以如果你沒有這樣做,它會標記出你的代碼可能意外行爲。在你的情況下,你正在做正確的事情,所以隨時忽略警告。 (事實上​​,在我的項目中,結構意味着我經常創建異常而不會因各種原因而拋出異常,所以我將警告降級到IntelliJ配置中的「信息」級別)。

2

這是一個奇怪的構造,但有一個解決方案的技巧的編譯器。
重寫你invalidInput方法扔IAE

private void checkInput() throws IllegalArgumentException { 
     if (...) 
      throw new IllegalArgumentException(); 

和:

try { 
     checkInput(); 
    } catch (IllegalArgumentException ex) { 
     throw new MyException(ex, arg1, arg2, ...); 
    } 
1

的IntelliJ不告訴你爲什麼。您只需閱讀檢查描述。

此檢查報告Throwable實例的任何實例,其中創建的Throwable從未實際拋出。大多數情況下,這是一個簡單的錯誤的結果。

相關問題