2つの質問があります:
- オーバーライドされたメソッドが新しいチェックされた例外をスローできないという制約の目的は何ですか?
- オーバーライドされたメソッドが、スーパークラスのオーバーライドされたメソッドのthrows句で指定された、すべてまたはまったく、またはチェックされた例外のサブセットのみをスローできるのはなぜですか?
2つの質問があります:
どちらの場合も、オーバーライドしている基本メソッドが呼び出し元のコードとのコントラクトを設定しているためです。メソッドがスローする可能性のあるチェック済みの例外に追加できる場合は、契約を破ることになります。
チェックされた例外をスローするBase
メソッドを持つクラスを考えてみましょう。から派生し、オーバーライドする もあります。のコードは変数を使用していますが、 の新しいインスタンスで初期化し、 を呼び出しています。コントラクトは、単に;をスローすることです。他のものを投げると契約が破られます。foo
SomeException
Derived
Base
foo
App
Base b
Derived
b.foo()
foo
SomeException
オーバーライド クラスは動作を追加できますが、削除はできません。例外をスローすることを宣言するメソッドは、動作です。
A
クラスとがあるとどうなるか考えてみてくださいB extends A
。
A
実装foo() throws MyException
し、B
実装しますfoo() throws OtherException
何が
A a = new B();
a.foo();
キャッチする必要がありますか?
ただし、B.foo()
が例外のサブセットのみをスローする場合 - それでも完全に安全ですが、呼び出し元の環境は、 がスローしたすべてのA
例外をキャッチ (またはスローしていると宣言) し、そうすることで、すべての B も処理します。
オーバーライドされたメソッドに新しくスローされた例外を追加できるとしましょう。
class AA{
void method() throws FileNotFoundException{}
}
class BB extends AA{
@Override
void method() throws FileNotFoundException, UnsupportedEncodingException {}
}
次に、オブジェクト BB への参照 AA を作成し、メソッドを呼び出します。
AA a=new BB();
try {
a.method();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
FileNotFoundException
コンパイラは例外のみをキャッチできUnsupportedEncodingException
、参照 AA から呼び出されるため、キャッチを許可しません。
ただし、オーバーライドされたメソッドにいくつかの種類の例外を追加できます
IOException
-> IOException, FileNotFoundException
) である場合は、チェックされるため、RuntimeException
s