2012-01-18 4 views
2

相反する例外仕様次のコードで

class MyException extends Exception{} 

interface Bread 
{ 
    public void eat() throws MyException; 
} 

interface Fringe 
{ 
    public void eat() throws RuntimeException; 
} 

public class Test implements Fringe , Bread // #5 
{ 
    public static void main(String[] args) 
    { 
     Fringe best = new Test(); // #1 
     best.eat();// #2 
    } 

    public void eat() throws RuntimeException // #3 
    { 
     System.out.println("Test"); 
     throw new RuntimeException(); // #4 
    } 
} 

MyExceptionRuntimeExceptionありません。 Test.eat()RuntimeExceptionと投げると宣言できますが、一般的なものはExceptionではありません。

+0

これはコードレントコードですか? MyExceptionは実際にはどこにでもスローされません。 – cha0site

答えて

4

これは、オーバーライドするメソッドでは、契約で定義されている例外以下の例外しかスローできないためです。したがって、eat()MyExceptionとそのサブクラスを投げることができますが、MyExceptionの上には何もありません。それはExceptionです。ランタイム例外はこのルールの一部ではなく、チェックされていないので自由に投げることができます。

TestクラスのインスタンスにアクセスするためにBreadインターフェイスを使用しているとします。 eat()メソッドを呼び出すと、MyExceptionが契約の一部であるため「確認」できますが、「高い」例外をスローすると決定した場合は、MyExceptionキャッチブロック内にキャッチされず契約に違反します。例えば、以下のコードを見て:

Bread b = new Test(); 
try { 
    // if this throws Exception, it won't be caught in the catch block 
    // thereby violating contract 
    b.eat(); 
} catch (MyException e) { 
    e.printStacktrace(); 
} 
2

2点:

  • それは、その後のどのeat()方法よりも一般的な例外をスローしていましたので、あなたは、Exceptionをスローすることを宣言することはできませんBreadインターフェイスが指定します。スーパークラスまたはインタフェースから継承されたメソッドは、スーパークラスまたはインタフェースで指定されたものよりも一般的な例外をスローすることはできません。
  • 句で指定したかどうかに関わらず、メソッドではチェックされていない例外を常にスローできるため、RuntimeExceptionをスローすると宣言できます。 (したがって、RuntimeExceptionを投げることを指定することは冗長です)。

私は最初のポイントで述べたルールの理由を説明するために:あなたがこれを行うとします

// Allowed because Test implements Bread 
Bread obj = new Test(); 

あなたが今obj.eat()を呼び出す場合、コンパイラはあなたが正しく、すべてのチェック例外を扱うかどうかを確認する必要がありますその呼び出しで発生する可能性があります。変数objのタイプを調べると、Breadとなります。 Breadインターフェイスは、eat()MyException(と暗黙的にサブクラスMyException)をスローできると指定します。

あなたTest.eat()方法は、このようなExceptionとして、チェック例外のより一般的な種類をスローさせた場合、コンパイラはちょうどあなたが正しく、すべてのチェック例外を処理objの種類を調べることで確認することができません。

この問題を回避するために、オーバーライドされたメソッドはより一般的な例外をスローすることができないというルールがあります。

0

オーバーライドするメソッドは唯一は、IS-オーバーライドされたメソッドでスローされた例外と関係を満たすこれらの例外をスローすることができます。

あなたは、インターフェイスがMyExceptionをスローしながら、自分のクラスでExceptionをスローするようにしようとすると...次の文がtrueの場合、コンパイラは、見ている:

例外がMyException-IS - 、それはあなたが知っている、偽です。コンパイラはそれを拒否します。

したがって、サブクラスのメソッドから特定の例外のみをスローすることができます。

あなたは実行時例外に関する質問のために:

実行時例外をスローするために、それはあなたが明示的に書かれていませんでしたかのように相当します。コンパイラはそれを無視します。たとえあなたがそれを言及していなくても、メソッドは実行時に例外をスローすることができるからです。

関連する問題