簡體   English   中英

調用拋出Checked異常的重寫方法

[英]Invoking overriding method that throws Checked exception

閱讀為什么不能覆蓋方法拋出異常 ,我理解如果聲明為拋出Checked異常的方法,子類中的重寫方法只能聲明拋出該異常或其子類:

class A {
   public void foo() throws IOException {..}
}

class B extends A {
   @Override
   public void foo() throws SocketException {..} // allowed

   @Override
   public void foo() throws SQLException {..} // NOT allowed
}

因為SocketException IS-A IOException我可以將重寫方法聲明為拋出IOException任何子類。

在我的程序中,我想調用聲明為拋出的重寫方法FileNotFoundException IS-A IOException 還使用try-catch塊處理

import java.io.*;
class Sub extends Super{
    public static void main (String [] args){
        Super p = new Sub();
        try {
            p.doStuff();
        }catch(FileNotFoundException e){

        }
    }
    public void doStuff() throws FileNotFoundException{}
}

class Super{
    public void doStuff() throws IOException{}
}

但我得到編譯時錯誤: 截圖

Sub.java:6: error: unreported exception IOException; must be caught or declared to be thrown
                    p.doStuff();
                             ^

這是什么原因? 我有點困惑,因為Base類也可用於子類。

除了IOException (與Overriding概念相反)之外,捕獲ExceptionThrowable的能力也更令人困惑。

您的對象引用是Super類型,即使您知道它在運行時是Sub對象。 因此,編譯器正在檢查Super的方法定義並為您提供此編譯錯誤。

它與獲取以下編譯器錯誤沒有什么不同:

Object o = new String("Hello World");
o.charAt(2); //Obviously not allowed

重要的是要記住throws子句是方法定義的一部分。

這是什么原因? 我有點困惑,因為Base類也可用於子類。

您需要捕獲IOException而不是FilenotFoundException 這是因為雖然子類中的doStuff方法將在運行時調用,但編譯器還不知道這一點。 它只知道超類中的doStuff方法,該方法聲明它throws IOException

解決編輯問題: catch塊可以選擇捕獲try塊中預期的確切異常,也可以選擇捕獲異常的超類。 這背后的原因與方法覆蓋沒有任何關系。

編譯器不考慮對象的類型,而是考慮您使用的引用類型,即Super

由於Super.doStuff() throws IOException ,這是你必須捕獲的。

順便說一下,我強烈建議使用IDE,你會發現它更有效率。

通過聲明p為超級

Super p = ...

你的編譯器只知道p是某種Super SuperdoStuff()拋出IOException ,但是你的代碼只捕獲IOException的特殊情況,即FileNotFoundException 如果你想告訴你的編譯器這肯定是Sub而不是Super只是將p聲明為Sub

在這種情況下,它不明確聲明為Sub ,但作為Super所以任何Super或其童車可能發生,並拋出任何IOException這可能不是一個FileNotFoundException或任何它的孩子的。

那是因為你使用的是靜態類型Super的對象。 編譯器無法知道在運行時p指向Sub對象,因此它希望捕獲由Super類中聲明的方法拋出的異常

因為它按聲明的類型進行檢查,在這種情況下是Super

不知道(或檢查)您的p將僅包含Sub實例。 此外,定義一個超類變量並僅使用它並且僅用於1個特定子類是沒有意義的。

所以你的Super p包含一個Super.class實例。 它的方法doStuff()可以拋出所有擴展IOException東西,比如說UnsupportedEncodingException ,但是你只能嘗試捕獲FileNotFoundException ,這樣就可能拋出了Unsupported...並且必須處理它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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