[英]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概念相反)之外,捕獲Exception
和Throwable
的能力也更令人困惑。
您的對象引用是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
。 Super
的doStuff()
拋出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.