2014-01-24 78 views
1

我試圖重寫的方法,以拋出一個異常:Java:如何重寫一個方法並拋出異常?

class A { 

    public doSomething(){ 
     // some of logic 
    } 

} 


class B extends A { 

    public doSomething() throws MyCustomizedException { 
     try { 
      // some of logic 
     } catch(ExceptionX ex) { 
      throw new MyCustomizedException(" Some info ", ex); 
     } 
    }  
} 

但我得到這個編譯時錯誤:

Exception MyCustomizedException is not compatible with throws clause in A 

兩個約束:

  • 使用如果它們存在,則函數的名稱和參數相同:doSomething()
  • 投擲我的定製異常

如何擺脫異常?

非常感謝。

+0

可能的重複[什麼原因異常不與throws子句兼容?](http://stackoverflow.com/questions/10513374/what-are-reasons-for-exceptions-not-to-be-兼容與投擲子句) –

+0

你得到我的一票。根本沒有事先研究的證據。 –

+4

您並未嘗試*重載*您嘗試*重寫*方法的方法(具有相同名稱的多個方法簽名)。 –

回答

0

這不是重載的情況。要重載,您需要具有相同簽名但參數列表不同的方法。這是重寫,如果A類可以修改,則在類A中使用public doSomething() throws MyCustomizedException {}

現在您可以使用您當前的B類實施覆蓋。

+0

只有A類是他的並且可以修改纔有可能。如果它是第三方庫,將無法使用。 – duffymo

+0

是的,這是問題所在。 A是第三方庫... – user3169231

4

無法完成。

當您重寫一個方法時,您不能破壞原始合同並決定拋出一個檢查的異常。您可以取消選中MyCustomizedException。你可以拋出它,但你不能要求用戶用一個檢查過的異常來處理它。你可以做的最好的事情就是將它添加到javadocs並解釋。

+2

這是*不*重載。 –

+0

雖然反過來是可能的。 – Mikhail

0

你可以做到這一點的唯一方法是使你拋出的異常延長RuntimeException而不是異常。

這樣你就可以拋出它,因爲你不改變方法的緊湊性,不幸的是,編譯器不會自動檢測到你需要捕獲該異常,但取決於你如何使用它,可能不會成爲一個問題。

+0

應該檢查我的自定義異常。它擴展了異常...:/ – user3169231

+0

我剛剛發佈了一個新答案。如果這不適合你,那麼你已經沒有選擇。 –

0

其實是有辦法做到這一點 - 使用組成,而不是繼承:

class B { 
    A a = new A(); 
    void doSomething() throws MyException { 
     a.doSomething(); 
     throw MyException(); 
    } 
} 

當然對此做你的B否不再計數爲A,從而不能被傳遞到任何期待的A.你可以在整個代碼中使用B,然後按需要換行。

+0

你失去了IS-A和多態性。 Liskov替換原則不會讓你使用B,無論你在哪裏A. – duffymo

+0

@duffymo當然。事實上,我的答案在最後一句中說過。如果OP不需要B作爲A來計算(這可能取決於他們在庫中做什麼,A和B是什麼等),那麼它解決了這個問題。 –