21

いくつかの異なる入力ファイルを解析する Java プログラムがあります。この入力ファイルでエラーが見つかった場合でも、解析は続行され、他のいくつかのエラーも収集される可能性があります。だから私がしたいのは、例外をスローして解析プロセスを停止する代わりに、例外をどこかに登録してから、同様の方法で解析を続けて他のいくつかのエラーを収集し、最後に確認したいエラーが報告され、これに応じて失敗または続行します。

もちろん、ExceptionRegister などのクラスを作成することで、いつでも手動でこれを行うことができますが、次の 2 つのことを知りたいと考えています。

1) このアプローチに問題はありますか? 私がやりたいことの代替デザインを知っていますか?

2) これを行う標準的な方法はありますか? (たとえば、独自のクラスをローリングする代わりに、可能であれば組み込み機能を使用したい)

ありがとう

編集:理由はわかりませんが、回答を受け入れる直前に誰かが回答を削除しました。とにかく、単純なデータ構造が機能するはずだと思います。基本的に、いくつかのエラー メッセージを収集する例外クラスを作成します。次に、少なくとも 1 つのエラー メッセージが登録されている場合に自身をスローする throw メソッドを呼び出します。

EDIT2:ここにさらに説明があります。私の問題は解析とは関係ありません。私のプログラムはいくつかの解析を行うため、解析は単なる例です。これを考えてみてください: 私はアルゴリズムを実行していて、エラーが発生した場合は、アルゴリズムを続行してさらにエラーを収集できるため、1 つのエラーを出力し、それが修正されたときに 2 番目のエラーを出力する代わりに、この 2 つのエラーを一緒に出力できます。

4

2 に答える 2

7

入力を処理できなくなった場合は、実際に例外を使用する必要があります。それらは、コードが「あきらめた、情報が不足している、またはこれを意図していなかった」と言う特別なケースです。これは、そのようなケースを定義する方法に関する灰色の領域ですが、Bill Venners がこの (古い!) 記事で述べているように、通常の哲学は次のとおりです。

メソッドの通常の機能の一部として合理的に予想できる条件を示すために例外を使用することは避けてください。

あなたの場合、解析する必要があるコンテンツが正しくないように思えますが、これはプログラムによって予期されており、解析を停止するのに十分な契約を破っていません。一方、許容可能な例外は、たとえば、入力の構文のエラーによって残りの解釈が失敗する場合に使用するのに有効です。

しかし、人々はまだ例外を使用しています。例外は、実行を停止してスタックを上に移動するのに非常に便利であり、結果の戻り値をフローするという面倒な詳細に入る必要がありません。しかし、対応するオブジェクトでは、一部のオブジェクトを無人状態のままにしておくと、トリッキーな結果になる可能性があります。

あなたの要件は、処理を停止させる可能性のある単一の例外よりも、検証パターンが必要であるように聞こえます。すべての処理を停止する 1 つの例外: 1 つをスローすると、残りは無視されます。でも、あなたはそれらを捨てるのではなく、集めることを提案しました。では、その場合、なぜ例外を使用するのでしょうか。適切な結果を返し、プログラムの実行を停止したくないようです。

それでもこの道をたどると、最後に例外のコレクションをスローする可能性があるためです。どれを投げますか?作成した例外コレクターで、どちらが優先されますか?

Eclipse の例を見てみましょう。Eclipse は、膨大なコレクションのプラグインの貢献を処理する巨大なプラットフォームを備えています。適切な通信チャネルを使用して、問題ペインまたはバックグラウンド タスクの実行を通じて、警告とエラーをログに記録します。後者の実行では、通常、IStatus オブジェクトまたはバリアントが返されます。このIStatusオブジェクトに基づいて、ステータスを受け取るコードはそれに基づいて行動することを決定します。

したがって、個人的には、必要なすべてのユーザー エラー (プログラムのエラーではなく) を収集し、プログラムの実行と契約の許容可能な部分を壊さない同様のオブジェクトを開発します。このオブジェクトには、エラーの重大度、そのソース、修正方法のヒント (文字列、またはエラーまたは部分的な自動修正を表示するための正確なロジックを含むメソッド) などを含めることができます。 .. 実行が完了すると、解析の結果がこれらのステータス オブジェクトを取得し、それに基づいて動作します。エラーが発生した場合は、UI を介してユーザーに通知し、ログにも記録します。

したがって、基本的には最初に提案したのと同じアプローチですが、例外を除いて、厄介な副作用とエラーのデバッグが非常に困難になる可能性のあるスタックをジャンプする商品を除いています。

于 2013-11-09T02:18:50.343 に答える
3

今なら分かると思います。実際にやろうとしているのは、解析エラー (例外として表している) を収集し、現在の入力ファイルの解析を続行することです。

これを行う標準的な方法はありません。

「例外レジスタ」は、実際には解析エラー記述子のリストにすぎません...おそらく何らかのパーサー例外です。適切な時点で例外をキャッチできる場合、それを「レジスタ」に追加するのは簡単です。

難しい部分は、あなたが話していない機能です:

  • エラーの場所をキャプチャする方法

  • パーサー エラーが発生したときにパーサーに解析を続行させる方法。

これらの解決策は、パーサーをどのように実装したかによって異なります。

  • パーサー ジェネレーターを使用している場合は、PGS のドキュメントで実装方法が説明されている可能性が高くなります。

  • パーサーを手動で実装する場合は、独自のコードをロールしてエラーの場所を追跡し、構文エラーの回復を行う必要があります。


基本的に、いくつかのエラー メッセージを収集する例外クラスを作成します。次に、少なくとも 1 つのエラー メッセージが登録されている場合に自身をスローする throw メソッドを呼び出します。

それは例外の乱用のように聞こえます。エラーをリストに蓄積し、リストが空でない場合は例外を作成/スローすることをお勧めします。コードの重複を避けたい場合は、ヘルパー クラスで静的メソッドを使用します。

条件付きでスローされる例外は (IMO) 奇妙です! また、スローする可能性が低い例外を大量に作成することは、非効率的である可能性があります。(JVM によっては、例外のコストのかかる部分は、多くの場合、例外の作成とスタック フレームのキャプチャです。コストはかなりのものになる可能性があります。)

于 2013-11-09T01:56:46.633 に答える