12

私の関数の多くには、宣言のすぐ下に検証コードが大量に含まれています。

if ( ! (start < end) ) {
    throw new IllegalStateException( "Start must be before end." );
    }

特定の入力の有効な範囲を正確に指定したい - たとえば、a > B、C => 1 または str_d.length() > 0。

一部の関数には検証が必要な引数が非常に多いため、前提条件を検証するためだけに多くのボイラープレートを作成することになります。私は、主に技術者以外の開発者が使用するライブラリを作成しています。関数入力を検証することが、ユーザーが API を正しく操作できるようにするための最良の方法であることがわかりました。エラーが発生するのが早ければ早いほど、お客様がしなければならない作業は少なくなります。

私の方法で事前条件、事後条件(およびおそらく不変条件)を指定するためのよりエレガントな方法はありますか?

同僚が Eiffel プログラミング言語の機能について教えてくれました。これにより、多くのボイラープレート コードを繰り返さずに、前/後/不変の条件を非常に自然な方法で記述できます。この魔法の一部を使用できる Java 言語へのアドオンはありますか?

4

8 に答える 8

13

GuavaPreconditionsクラスはまさにこのためのものです。通常、静的インポートで使用するため、例は次のようになります。

checkArgument(start < end, "Start must be before end");

Stringチェックに合格した場合に連結のコストを支払うことなく、メッセージに情報を追加することも簡単になります。

checkArgument(start < end, "Start (%s) must be before end (%s)", start, end);

ステートメントとは異なりassert、これらを無効にすることはできません。

于 2011-07-25T12:56:34.370 に答える
6

アノテーションを通じて Java のコントラクトを提供するCofojaプロジェクトを調べてください。事前/事後条件と不変条件を提供します。また、他の Java 実装とは対照的に、親クラス/インターフェースで定義されたコントラクトを正しく処理します。コントラクトの評価は、実行時に有効または無効にすることができます。

チュートリアルのコード スニペットは次のとおりです。

import com.google.java.contract.Invariant;
import com.google.java.contract.Requires;

@Invariant("size() >= 0")
interface Stack<T> {
  public int size();

  @Requires("size() >= 1")
  public T pop();

  public void push(T obj);
}
于 2011-07-25T23:10:04.270 に答える
5

どうですかassert start < endドキュメントをご覧ください。

于 2011-07-25T12:47:58.220 に答える
4

アスペクト指向プログラミングは、このような問題に使用できます。メソッド呼び出しは、不変条件のチェックを傍受できます。ポイントカットとアドバイスは、宣言的な方法で構成されます。SpringGuiceを使用すると、AOP を簡単に使用できます。

Guiceの例を次に示します。

于 2011-07-25T12:51:01.680 に答える
4

アノテーションとアスペクト指向プログラミングでこれを行うことができるかもしれません。

引数の組み合わせが正しくない場合は、IllegalArgumentException を使用します。IllegalStateException は、メソッドが機能しない状態にあります。

例外のヘルパー メソッドを作成できます。

public static void check(boolean test, String message) {
    if(!test) throw new IllegalArgumentException(message);
}

check(start < end, "Start must be before end.");
于 2011-07-25T12:51:39.563 に答える
1

入力の検証には、 Apache Commons Validatorも使用できます。

入力検証は常に有効にする必要があることに注意してください。したがって、アサーション チェック (Eiffel など) とは概念的に大きく異なります。アサーション チェックは、オプションでオン/オフを切り替えることができます。この関連するスタック オーバーフローの質問への回答を参照してください。 「assert」キーワードを使用するだけですか?

于 2012-04-26T20:32:39.623 に答える
-2

JUnitパッケージには、このような条件チェックを行うのに役立つ assert のような構造があります。

于 2011-07-25T12:51:00.450 に答える