簡體   English   中英

抽象方法中的多態和檢查異常拋出

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM