5

Guava は前提条件をチェックするヘルパー関数を提供していますが、中間結果をチェックするヘルパー関数が見つかりませんでした。

private void foo(String param)
{
    checkNotNull(param, "Required parameter is not set");

    int x = get(param);
    if (x == -1) {
        throw new RuntimeException("This should never have happened and indicates a bug.");
    }
}
  • if (...) {....}自分のヘルパーでパーツ をラップする必要がありますか?
  • またはcheckState、グアバから使用する必要がありますか?
  • または、 の失敗をget()の結果と見なしてparamを使用する必要がありますcheckArgumentか?
  • これらの場合、アサートを使用する必要がありますか?
  • または、何か不足していますか?
4

4 に答える 4

7

それは好みの問題と慣習の問題の間のどこかです。

一般に、人々は assert を使用してプログラミング エラーを示します。つまり、「私が自分の仕事を正しく行っていれば、ユーザー入力やその他の外部の力に関係なく、 null 以外の結果が -1 になることはありparamません。」get私はそれらをほとんどコメントとして扱い、オプションで実行時に検証することができます。

一方、場合getによっては -1 を返す可能性がありますが、その入力が無効な場合は、通常、 をスローIllegalArgumentExceptioncheckArgumentます。これは、これを行うための完全に合理的な方法です。これの欠点の 1 つは、後でそれを見つけたときに、ほとんどどこからでも来た可能性があることです。検討:

try {
    baz();
    bar();
    foo(myInput);
} catch (IllegalArgumentException e) {
    // Where did this come from!?
    // It could have come from foo(myInput), or baz(), or bar(),
    // or some method that any of them invoked, or really anywhere
    // in that stack.
    // It could be something totally unrelated to user input, just
    // a bug somewhere in my code.
    // Handle it somehow...
}

それが重要な場合、たとえば、ユーザーが入力フォームに入力することを許可されていないことをユーザーにポップアップ表示したい場合など-1、カスタム例外をスローして、より簡単にキャッチできるようにすることができます。それは後で:

try {
    baz();
    bar();
    foo(myInput);
} catch (BadUserInputException e) {
    reportError("Bad input: " + e.getMessage());
    log.info("recorded bad user input", e);
}

に関してはcheckState、私には正しく聞こえません。この例外は通常、問題があった状態this(または、アプリケーション内の他のよりグローバルな状態) にあったことを意味します。ドキュメントから:

メソッドが不正または不適切なタイミングで呼び出されたことを示します。

あなたの場合、 -1 は決して適切ではないため、checkState誤解を招きます。今、それがあった場合:

if (x == -1 && (!allowNegativeOne()) { ... }

...それなら、上記の欠点がまだありますが、より適切IllegalArgumentExceptionです。

最後に、 をそのままにifしておくべきか、それともヘルパー メソッドを使用するべきかという問題があります。それは、好み、チェックの複雑さ、使用頻度 (他の方法など) にかかっています。チェックが単純でx == -1、そのチェックが他の方法で実行されない場合 (コードの再利用は問題になりません) if、.

于 2013-02-22T12:04:40.743 に答える
2

メソッドが単純に文字列を int に変換している場合getは、そこで検証を行う必要があります。できれば、 illegalArgumentException またはそのような RuntimeException をスローします。上記では、メソッドに抽象化のレベルも混在しています。たとえば、nullcheckNotNullのチェックを抽象化しますが、int としてのチェックはメソッドとメソッドに分割されます。checkPreCondition タイプのメソッドが 1 つないのはなぜですか? 例えばparamparamgetfoo

private void paramShouldBeNonNullInt(String value) {
    if (value == null) throw new IllegalArgumentException("value was null");
    try {
       Integer.parseInt(value)
    } catch (NumberFormatException  e) {
        throw new IllegalArgumentException("value was not an integer");
    }
}
于 2013-02-22T11:41:44.423 に答える
0

ここにいくつかの他の優れた答えがあります。

前提条件javadocから:

前提条件例外は、呼び出し元のメソッドがエラーを起こしたことを通知するために使用されます。(...) 事後条件またはその他の不変の失敗は、これらのタイプの例外をスローすべきではありません。

そう ...

自分のヘルパーで if (...) {....} 部分をラップする必要がありますか?

いいえ、既存の設備で十分です。

または、Guava の checkState を使用する必要がありますか?

はい、おそらく: このメソッドが呼び出される前にパラメータをファイルからロードする必要がある場合、それはこのクラスの使用方法の契約の一部になります。

または、get() の失敗を param の結果として表示し、checkArgument を使用する必要がありますか?

はい、可能です: たとえば、パラメーターの構文に何らかのフォーマット制限があった場合。(たぶんそれは中に入るでしょうがget()

これらの場合、アサートを使用する必要がありますか?

はい。上記のような前提条件チェックでない場合は、通常はここを使用しassertます。メッセージを追加できることを忘れないでください。

assert x != 1 : "Indicates a bug.";

これは、期待を文書化し、クラスまたはメソッドの内部/プライベート実装を検証するのに適していると思います。

実行時チェックを行いたい場合は実行できますif (...) throw AssertionErrorが、信頼できない危険なコードを使用している場合にのみ必要です。

于 2015-06-11T22:51:57.313 に答える