1

次のようなJavaクラス階層について考えてみます。

abstract class Exp { public void generate(); }
class EffExp extends Exp {...}
clas PureExp extends Exp {...}
class NewExp extends EffExp {...}
etc, etc.

generateInsideの実装は、NewExpをスローするように変更されましたIOException

public void generate() throws IOException {...}

の他の実装はIOをgenerate実行しないため、IOをスローする必要はありません。コンパイラは文句を言い、例外をスローするためにクラス階層内のすべてのメソッドを宣言するように強制します。これは本当に前進する唯一の方法ですか?かなり煩わしいようです。

もちろん、内部でそれが発生する例外をキャッチすることはできますが、それNewExpは実際には意味がありません。例外は最上位に伝播し、プログラムの実行を停止する必要があります。

ここでのより一般的な質問は、相互にオーバーライドするメソッドの階層がある場合、同じ例外のセットをスローするようにすべてを宣言する必要があるかどうかです。

4

7 に答える 7

1

シナリオが次のようなものであるとします。

abstract class Exp { public void generate(); }
class EffExp extends Exp { public void generate throw IOException(....)....}
clas PureExp extends Exp {public void generate(....)....}

実際の実装を気にせずに他のクラスを実装できるように、抽象クラス表記を使用します。実際に作ると・・・ 実装が狭められました。つまり、場合によっては例外をスローし、他の場合にはスローしない場合、明らかに Java がロバストであることに違反しています。したがって、明確に同期する必要があります。すべての方法について。

親の「例外」をスローすることで可視性を高めることができますが。

于 2012-12-17T11:53:47.937 に答える
1

1つのルールを覚えておいてください: -

  • オーバーライドするメソッドに制限を追加することはできません。制限の例: - 新しい の追加Checked Exception、メソッドの可視性の低下。

したがって、(選択の余地がない) 必要がある場合は、オーバーライド メソッドでスローするようにしますChecked Exception(チェックされていない例外を追加することはできますが、意味がないことに注意してください)。オーバーライドしているメソッド。

したがって、簡単に言えば、overriddenメソッドのシグネチャは、それをオーバーライドするシグネチャと正確に一致する必要があります。


これの背後にある単純な理由は -Polymorphismです。

ポリモーフィズムでは、ご存知のようsuper typeに、サブクラス オブジェクトへの参照ポイントを持つことができます。だから、あなたが持つことができます: -

SupClass ref = new SubClass();
ref.method1();

現在、 の存在をチェックしている間method1、コンパイラは参照型のみを考慮しています。そのため、チェックインしSupClass、それに応じてアクセスを許可します。

ここで、実行時にが実際にオブジェクトをref指しているときに何が起こるか想像してみてください。クラッシュします。それが許可されていない理由です。SubClassmethod1compiler

于 2012-12-17T11:43:44.797 に答える
1

抽象クラスでは、java.lang.Exception をスローするように定義できます。

abstract class Exp { public abstract void generate() throws Exception; }

また、派生クラスでは、スローする例外の種類をより具体的にします。

于 2012-12-17T11:56:40.187 に答える
0

この単純な架空のコードを考えてみてください。これは...あなたの説明に合うと仮定しましょう。

Exp ex = new NewExp(); 
try {
ex.generate(); //It should throw an exception, but has no such method signature. 
} catch(AnException e) { //Nope, not allowed.
 ...
}
于 2012-12-17T11:46:32.580 に答える
0

メソッドをオーバーライドしている場合、スーパークラスでオーバーライドされたメソッドは、その例外 (チェック済み) またはそのスーパークラスをスローすることのみを宣言できます。そうしないと、ポリモーフィズムが失われ、Java で許可されなくなります

于 2012-12-17T11:51:59.573 に答える
0

チェック例外をスローする必要がありますか。ランタイム例外でラップできますか?

public void generate() {
     try {
     ....
     } catch (IOException e ){
        RuntimeException re = new RuntimeException();
        re.initCause(e);
        throw re;
     }   
}

(コンパイルのためにこれをチェックしていませんが、一般的なアイデアが得られるはずです

于 2012-12-17T11:49:50.640 に答える