[英]Polymorphism and checked exception throwing in abstract methods
假設我們有一個帶有一個可能拋出IOException
方法的Foo
類。
public abstract class Foo {
public abstract void foo() throws IOException;
}
但是,當我將類擴展為FooImpl
如下所示:
public class FooImpl extends Foo {
public void foo() throws Exception {
throw new Exception("This cannot throw!");
}
}
這將導致編譯時錯誤:“覆蓋的方法不會引發java.lang.Exception”
我了解這是因為覆蓋方法“可能只拋出其父方法的檢查異常以及任何未檢查的異常”
為什么會這樣呢? 為什么我們應該禁止自己拋出更廣泛的例外?
(我也在尋找解決方法)
謝謝!
您必須始終能夠在使用超類的任何地方使用其子類。 從字面上看,這幾乎就是子類的定義,並且通常被稱為Liskov替換原理 。
因此,鑒於Foo
定義,以下必須工作:
Foo foo = getFooFromSomewhere();
try {
foo.foo();
} catch (IOException e) {
// handle e
}
...因為符合Foo
的定義。
對於這個定義的FooImpl
,那就沒辦法了,因為Exception
是不發IOException
都沒有處理,並作為檢查的異常必須被捕獲或者以其他方式處理。
這是因為超類所建立的合同。 換句話說,當編譯器“驗證”重寫的方法時,它保證可以使用子類的實例針對超類型的API進行編程。
實際上,如果您有
Foo foo = some foo implementation;
try {
foo.foo();
} catch(IOException ioe) {
//handle IOException
}
該catch
塊應足以處理Foo
API的已檢查異常。 但是,如果編譯器讓子類引發超類聲明的異常以外的其他檢查異常,例如Exception
,那么針對Foo
進行編程並處理所有聲明的檢查異常將是不夠的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.