2012-05-09 12 views
14

誰でも句たとえば例外がスロー句と互換性がない理由は何ですか?

「スロー」と互換性がないように、例外が持つことができる理由から何を教えてもらえます:

class Sub extends Super{ 

    @Override 
    void foo() throws Exception{ 

    } 

} 

class Super{ 

    void foo() throws IOException{ 

    } 
} 

例外例外はSuper.foo(中throws節と互換性がありません)

+1

問題を示す完全なコードをお知らせください。 'Exception'の完全修飾クラス名も含みます。 –

+1

あなたはあなたのコードとあなたが得ている正確なエラーのビットをさらに表示できますか? – aniri

+0

鉱山が動作します。それよりも多くのコードを表示する必要があります。 – Averroes

答えて

22

完全なコードサンプルがないと、私は推測できます:あなたはサブクラスでメソッドをオーバーライド/実装していますが、サブクラスメソッドの例外仕様はスーパークラスの例外ではありません(つまりサブセットではありません) /インターフェイスメソッド?

これは、例外を全くスローしないように基本メソッドが宣言されている場合に発生します。 java.io.IOException(あなたのメソッドがここに投げようとしているjava.lang.Exceptionのサブクラスです)。基本クラス/インタフェースのクライアントは、そのインスタンスが基本メソッドによって宣言されたコントラクトを遵守することを期待しているため、そのメソッドの実装からExceptionを投げるとコントラクト(およびLSP)が破損します。

+0

PéterTörök-ありがとうございました –

+0

Iそれはディスカッションサイトではないことを知っていますが、LSPが**何かを追加することができない理由を理解していません。 –

+6

何かを追加することができます。しかし、オーバーライドされたメソッドに例外の型を追加するときに、何かを追加するのではなく、何かを削除しているときは、基本クラスでは例外が発生することはありませんが、サブクラスではこの保証が失われます。それが禁止されている理由です。 –

-1

チェック例外は、呼び出し元が発生する可能性がある特定の問題に対処する準備ができていると予測される状況での使用を想定しています。 BaseFoo.Bar()の発信者がFnordExceptionを処理する必要がない場合、方法DerivedFoo.Bar()は、その発信者がFnordExceptionのいずれかの対処を期待できません。(発信者の多くは準備が整っていないので、BaseFoo.Bar()を投げます。

概念的には、それは素晴らしいです。実際にはそうではありません。問題は、言語でチェックされた例外の設計では、呼び出し元が特定の問題を正常に処理する用意ができていないか、すべての呼び出し元が対処する用意があることが前提であるということです。実際の通常の状態は、発信者が例外を処理する準備ができていないことです。たとえ一部の発信者が処理できる場合でも例外です。ほとんどの場合、コードが未チェックの例外を受け取って明示的に予期していないと判断された場合、未確認の例外にそれをラップしてそれをスローすることが適切なアクションです。皮肉なことに、「スロー」句を追加し、チェックされた例外をバブルアップさせるアクションの最も簡単なコースは、おそらく正しいものではない可能性が最も低いものでしょう。このような動作が意味をなさない場合(例:IOException)、ファイルからコレクションを読み込もうとすると、コレクションを読み取っているときにI/Oエラーが発生してI/Oエラーが発生する場合があります。ネストされたメソッド呼び出しからスローされた例外は、外部メソッドによってスローされる同じ型の例外とは異なる条件を表し、後者を処理するために用意されるコードは前者を処理する準備ができていない可能性があります。

場合によっては、IOExceptionをキャッチして、RuntimeExceptionから派生した他のタイプのラップにすることをお勧めします。発信者がそれを処理する可能性は低いことに注意してください。 のRuntimeException

public T findById(long id) throws RuntimeException { 
    try { 
      return whatEver.create(); 
    } catch (SystemException e) { 
      throw new RuntimeException(e); 
    } 
} 

・ホープこのことができますを使用して、それを修正するには

-1

あなたのインターフェイスにthrowを宣言してください。それでも問題は解決しない場合は、プロジェクトを保存/再構築してみてください。

+0

私はこれが行く方法だとは思わない。 –

関連する問題