3

メソッドのシグネチャによって必ずしもリストされていない、スローされる可能性のあるすべての例外を把握することは可能ですか。

2ケースあります

1) 宣言する必要のない実行時例外 (明らかに、null ポインターなどのいくつかは明白ですが、開発中に私が行っていない、不良データが原因である可能性がある他の実行時例外をキャッチしたい場合があります)悪いデータかどうかはまだわかりません)。

2) シグネチャにリストされた例外のサブクラスである例外。

モチベーションの例

HttpURLConnection オブジェクトで getInputStream() を呼び出すと、java.io.Exception がスローされますが、実際には、java.io.Exception (ala java.io.FileNotFoundException) のサブクラスである他の例外がスローされます。独自の方法で処理する (つまり、すべての java.io.Exception をひとまとめにしたくない)。

したがって、実際には java.io.Exception をキャッチして実際の例外を出力し、そのケースを処理するようにコードを変更することで学習できますが、より良い方法があるかどうか疑問に思っていました:)

ありがとう

編集:人々は私の2番目の問題を見逃していると思います。メソッドのシグネチャと完全に一致するチェック例外をスローするメソッドですが、メソッドのシグネチャにはある種の基本クラスしかないため、メソッドのシグネチャにはリストされていません。

4

4 に答える 4

2

いいえ。原則として、実行時にCLASSPATHにどの例外クラスが存在するかを事前に知ることはできません。また、探しているインターフェイスを実装する可能性のあるクラスのセットを事前に知ることもできません。クラスまたはメソッドがfinalでない限り、表示しているクラスを拡張し、メソッドをオーバーライドします。あなた自身の例はその好例です:あなたは見ていますがHttpURLConnection、それは抽象クラスであり、実行時に表示される実際の実装クラスは構成によって異なります:使用されるHTTPURLStreamHandlerクラスは1つを使用するように再定義できますの異なる実装を返しますHttpURLConnection

于 2012-08-12T04:14:47.680 に答える
2

メソッドのシグネチャによって必ずしもリストされていない、スローされる可能性のあるすべての例外を把握することは可能ですか。

簡単な答え: そうではありません。

私の答えはこのドキュメントに大きく基づいているため、このドキュメントを読んで、Java 設計者が考えられるすべての例外を処理する必要がなかった理由を理解することをお勧めします。unchecked exceptionドキュメントに記載されている理由は次のとおりです。

ランタイム例外は、プログラミングの問題の結果である問題を表しており、そのため、API クライアント コードがそれらから回復したり、何らかの方法でそれらを処理したりすることは合理的に期待できません。このような問題には、ゼロ除算などの算術例外が含まれます。null 参照を介してオブジェクトにアクセスしようとするなどのポインター例外。大きすぎるか小さすぎるインデックスを介して配列要素にアクセスしようとするなど、インデックス例外。

実行時例外はプログラムのどこでも発生する可能性があり、通常の例外では非常に多く発生する可能性があります。すべてのメソッド宣言に実行時例外を追加する必要があると、プログラムのわかりやすさが低下します。したがって、コンパイラは実行時例外をキャッチまたは指定する必要はありません (可能ですが)。

したがって、私の意見では、考えられるすべての例外を探すのは得策ではありません。たとえば、意味がありませんOutOfMemoryError。実際、そのような例外をキャッチすることも悪い習慣と考えられています。

于 2012-08-12T03:32:17.227 に答える
1

これは難しい問題です。

比較的単純な「非解決策」があります。静的アナライザーは、アプリケーションのクラス ライブラリで利用可能な未チェックの例外をすべて列挙できる必要があります。チェックされた例外のすべてのサブクラス。もちろん、それは多くの誤検知をもたらします。つまり、メソッド シグネチャで許可されているにもかかわらず、呼び出しでスローできない可能性がある例外です。

実際にスローされる可能性のある例外を見つけるには、何らかのバイトコードまたはソースコード操作フレームワークを使用してコードを分析する必要があります。特定のメソッド呼び出しで使用される可能性のある Java メソッドのクロージャーで言及されているクラスの例外クラスのセットを判別できる必要があります。ただし、一部の例外は Java コードでは言及されていません。これには、JVM 自体によってスローされる実行時例外とエラー、およびネイティブ コード ライブラリによってスローされる可能性のあるその他の例外が含まれます。また、例外をスローするコードが実行時に挿入される可能性があります。たとえば、動的プロキシを使用します。最後に、一部の例外は、特定のアプリケーションでは不可能であることが証明されている状況でのみスローされるという問題があります。


そのため、java.io.Exception をキャッチして実際の例外を出力し、そのケースを処理するようにコードを変更することで実際に学ぶことができますが、より良い方法があるかどうか疑問に思っていました。

ええ。より適切な方法は、javadoc を読み、常識を働かせてどの例外が発生する可能性があるかを判断し、疑問がある場合はソース コードを読むことです。

もう 1 つのポイントは、一般的に言えば、例外を効果的に処理するために、考えられるすべての例外を知る必要はないということです。

最後に、スローされる実際の例外は JVM ごとに異なる可能性があるため (これらは実装の詳細です!)、どの例外がスローされる可能性があるかを正確にコードで想定することはお勧めできません。

于 2012-08-12T03:32:41.407 に答える
0

バイトコード レベルでは、チェック済み例外は存在しないため、バイトコード メソッドを呼び出す場合は、メソッド シグネチャに関係なく、何でもスローできます。これは、リフレクションまたはカスタム クラスローダーを使用して、純粋な Java から同じことができることも意味します。

を使用してコードに例外をスローさせることもできますThread.stop

于 2012-08-12T03:32:52.157 に答える