Javaの道 Javaに関する
 ニュースJava基本Servlet・JSPオープンソースFAQ掲示板
Javaの道 > Java基本 > 例外 −4.アサーション
更新日:2005/8/2
例外−4.アサーション
ここでは、J2SE 1.4から導入されたアサーションについて解説します。
概要
アサーションとは、バグの少ないプログラム開発を補助する機能です。プログラムコード中に、ある特定の条件をアサーションで記載しておきます。その条件を満たさない場合は、AssertionErrorが返されます。そうすることにより、バグの箇所を早期に発見できるようになります。
----- プログラム処理A -----

//この位置で変数iが0の場合、AssertionErrorが返されます。
assert i != 0 ;

----- プログラム処理B -----

//この位置で変数iが0以上でない場合、AssertionErrorが返されます。
assert i > 0 ;

----- プログラム処理C -----
アサーションとは、バグの少ないプログラム開発を補助する機能です。プログラムコード中に、ある特定の条件をアサーションで記載しておきます。その条件を満たさない場合は、AssertionErrorが返されます。そうすることにより、バグの箇所を早期に発見できるようになります。
基本仕様
アサーションはassertの後にbooleanを返す式1を記載します。trueが返る場合は何もおきませんが、falseが返る場合はAssertionErrorが返されます。
式2を記載した場合は、AssertErrorが返された場合に、詳細メッセージとして式2を実行した実行結果が表示されます
assert 式1 ;
assert 式1 : 式2 ;
javacコマンドでコンパイルする際、オプションに-source 1.4を指定することで、アサーションを有効にできます。指定しない場合は、アサーションは無効です
javac -source 1.4 xxx.java
javaコマンドでプログラムを実行する際、オプションに-eaもしくは、-enableassertionsを指定することで、アサーションを有効にできます。指定しない場合は、アサーションは無効です
java -ea xxx
java -enableassertions xxx
※この他特定のパッケージ内のみアサーションを有効にするなど、アサーションの有効範囲を細かく指定することもできます。詳細はアサーションのJava APIドキュメントをご参照ください
利用方法
事前条件、事後条件、クラスの不変条件
アサーションを利用する際の基準として、「事前条件」、「事後条件」、「クラスの不変条件」の各条件に合わせて利用することがよいとされています。各条件はすべてのケースにおいて当てはまるわけではありません、環境にあわせ条件の設定を行います。

「事前条件」
メソッドの引数が満たしておくべき条件。この条件がエラーになると、メソッド呼び出し前のプログラムコードにバグがあることを表します。

「事後条件」
メソッドの処理終了時点で満たしておくべき条件。この条件がエラーになると、メソッド内のプログラムコードにバグがあることを表します。

「クラスの不変条件」
クラスのオブジェクトが満たしておくべき条件。メソッド実行前と、メソッド実行後にこの条件を確認します。 メソッド実行前にこの条件がエラーになると、メソッド呼び出し前のプログラムコードにバグがあることを表します。メソッド実行後にこの条件がエラーになると、メソッド内のプログラムコードにバグがあることを表します。 不変条件の例としては、クラスのメンバ変数に正しい値が設定されているか。メンバ変数同士の関係は正しいか。などがあります。
publicなメソッドの引数チェックは行わない
publicなメソッドの引数チェックは、通常のプログラムコードの中で常に行われるべきであり、アサーションを利用して行うべきでないとされています。
プログラムで必要な処理をアサーションで行わない
プログラムで必要な処理をアサーションで行うべきではありません。変数xを10倍する処理があった場合、「assert x * 10 > 100;」と記載するとアサーションを利用しない場合10倍する処理が行われません。この場合は、「x = x * 10;」「assert x > 100;」と記載します。
利用例
アサーションの利用例を以下に記載します。引数x、yを持ち、xをy回分加算するcalNumメソッドにアサーションを設定した例です
【例1】
public class ExAssert {
  public static void main(String[] args) {
    ExAssert object1 = new ExAssert();
      object1.calNum(5, 10);
  }
    
  void calNum(int x, int y) {
    int z = 0;
    //(1)事前条件
    assert x > 0 && y > 0:"xまたはyが0以下です。";

    //(2)変数xを変数y回、加算
    for (int i = 0; i < y; i++) {
      z = z + x;
    }

    //(3)事後条件
    assert z >= x && z >= y:"zがxまたはyより小さい値です。";

    System.out.println(z);
  }
}

【解説1

(1). 事前条件として、引数x、yが0より大きな値であることを設定しています。0以下である場合、AssertionErrorが返されます。
(2). forループを利用し、xをy回分加算しています。xをy回分加算した結果は変数zに代入されます。
(3). メソッドの事後条件として、変数zが引数x、y以上であることを設定しています。x、y未満である場合、AssertionErrorが返されます。
【実行結果1(AssertionError無し)】
C:\source>javac -source 1.4 ExAssert.java

C:\source>java -ea ExAssert
50

C:\source>
【実行結果1(forループの処理をコメントアウトしてAssertionErrorが発生)】
C:\source>javac -source 1.4

ExAssert.java C:\source>java -ea ExAssert

↓forループ処理が実行されていないため、事後条件に違反し
↓AssertionErrorが返されています。

Exception in thread "main" java.lang.AssertionError: zがxまたはyより小さい値です 。
   at ExAssert.calNum(ExAssert.java:15)
   at ExAssert.main(ExAssert.java:4)

C:\source>



このページのトップへ
 ニュースJava基本Servlet・JSPオープンソースFAQ掲示板
Javaの道_CopyrightJavaの道