2015-10-07 61 views
5

爲什麼拋出方法的一部分簽名。包含它似乎很奇怪。這是一個例子。爲什麼拋出方法簽名的一部分

@Overide 
public void foo() { 
    throw new UnsupportedOperationException(); 
} 

如果有誰在哪裏看到這個方法從他們可能會嘗試使用它,而不知道它是不支持外。他們只會在嘗試運行代碼時學習它。

但是,如果他們可以做這樣的事情,他們會通過查看它不被支持的方法知道,如果UnsupportedOperationException沒有擴展RuntimeException,他們會得到一個編譯錯誤。編輯1:但這是不可能的,因爲拋出是簽名的一部分,所以重寫將不起作用。

@Overide 
public void foo() throws UnsupportedOperationException { 
    throw new UnsupportedOperationException(); 
} 

這個問題涉及Java類的設計,所以我知道這可能是很難回答不上它的工作滴通過並回答它的人之一,但我希望,也許這問題已經被問到他們在此之前或者可能有明顯的理由通過這種方式來解釋原因。

+3

你似乎在這裏回答你自己的問題?這是簽名,因爲你(和編譯器)知道代碼將拋出異常並且需要處理? – Erik

+3

未檢查的異常及其引發的條件應記錄在javadoc中。這種範例被用在內置的Java庫中,並由多本書建議,例如,有效的Java來命名一個。 正如您正確指出的那樣,在簽名中聲明它們不是編譯器所要求的。 – Danstahr

+0

你在質疑的是是否拋出一個未檢查的異常。爲了啓動你的方法,使用'@ Override'來表示它應該遵循契約(抽象或接口),但對於未經檢查的異常,你沒有義務這樣做。無論你是否選擇拋出它,總是按照@danstahr提到的良好實踐,將它添加到javadoc中。 –

回答

4

throws部分並不表示該方法是需要拋出所提及的例外,甚至沒有在特定的ocations。它只是告訴該功能被允許這樣做。

包括throws UnsupportedOperationException因此並不意味着該方法不受支持。除了UnsupportedOperationExceptionRuntimeException所以一個方法可能throw反正。

現在由於原因,人們會在方法的簽名中要求它,它歸結爲檢查異常的能力。爲了讓編譯器能夠決定一個方法是否只能拋出指定的異常,它必須能夠決定它調用的方法不能拋出未捕獲的異常。

這意味着例如重寫一個方法意味着你不能添加可能被拋出的異常,否則你將破壞驗證調用該方法的方法不能拋出其他東西的可能性。另一種方法是可能的(但我不確定Java是否支持這種方法),重寫一個可能拋出的方法。

因此,例如:

class B { 
    int fubar(int) throws ExceptionA { 
    } 

    int frob(int) throws ExceptionA { 
     return fubar(int); 
    } 
} 

class D extends B { 
    int fubar(int) throws ExceptionB { 
    } 
} 

現在frob被指定爲可能throwExceptionA,但在調用this.fubar它會打開別的東西被拋出的可能性,但fubar被定義爲可能只有throwExceptionA。這就是爲什麼D.fubar是一個無效覆蓋,因爲這會打開this.fubar實際上拋出ExceptionB的可能性,編譯器將無法保證frob不會拋出ExceptionB

2

Java有兩種不同類型的異常:checked異常和 unchecked例外。

未經檢查的異常是RuntimeException的子類,您不必添加throws聲明。所有其他異常都必須在方法體中處理,可以使用try/catch語句或throws聲明。

未檢查異常的示例:IllegalArgumentException有時用於通知已使用非法參數調用某個方法。沒有投擲需要。

檢查異常的示例:IOException來自java.io包的某些方法可能會拋出異常。使用try/catch或向方法聲明中添加拋出IOException並將方法調用者的委託異常處理。

相關問題