2014-12-19 108 views
6

考慮以下接口:爲什麼拋出異常的方法的調用者在這種情況下不必處理異常?

package hf; 

public interface BadInterface 
{ 
    void meth() throws Exception; 
} 

這是由以下類實現:

package hf; 

public class apples implements BadInterface 
{ 
    public static void main(String[] args) 
    { 
     new apples().meth(); 
    } 

    public void meth() 
    { 
     System.out.println("Ding dong meth."); 
    } 
} 

雖然甲基()是拋出異常,該方法甲基的呼叫者的方法()是不必處理或聲明異常,但程序仍能成功運行。爲什麼會這樣? 這是否違反了規則:每當調用引發異常的方法時,都需要捕獲異常或聲明自己拋出異常?

+0

您應該將您的類重命名爲「Apple」以匹配Java編碼規範。 – 2014-12-19 13:05:00

回答

7

當你實現一個接口的方法,你被允許聲明你扔比在界面中列出例外。

當您致電new apples().meth()時,您在調用​​實例時調用meth()。編譯器知道這不會拋出任何東西,所以你很好。

假如你做了:

BadInterface foo = new apples(); // Note: should be Apples (code style) 
foo.meth(); 

那麼你就需要趕在接口中聲明的例外,因爲編譯器只知道它在處理一個BadInterface實例。

+0

另請注意,異常不是方法簽名的一部分。這就是爲什麼你可以實現這個方法,而不必爲它添加'throws Exception'。例如,您也可以添加異常:'public void meth()拋出IOException異常,FooException異常' – Davio 2014-12-19 12:01:42

+1

@Davio例外在簽名中肯定是相關的 - 例如,您不能拋出未在接口中列出的任何已檢查的異常。 – 2014-12-19 12:03:34

+1

最近,更適合的術語是「形狀」,與lambda轉換相關。聲明的異常肯定會影響方法的形狀。 – 2014-12-19 12:07:40

0

根據JLS Requirements in Overriding and Hiding

B是一個類或接口,而A是一個超類或B的超接口,和B中替換方法聲明m 2或在A.隱藏方法聲明M1然後:

對於每一個檢查中所列出的異常類型的拋出M2, 子句相同的異常類或它的超類型必須發生在 擦除(§4.6)的拋出的M1子句中的一個;否則,發生編譯時 錯誤。

就是說擴展方法只能有較強的異常策略。如果它具有較弱的限制,則不能使用這種方法代替基本方法,並且會打破重寫的概念。

相關問題