平鍋です.
On Tue, 26 Dec 2000 15:28:38 +0900,
森末 吉彦 <Morisue_Yoshihiko@....jp> said:
> 具体的なメリットがよくわからないのですが、assertionが使えば
> たとえばどんなシチュエーションで楽になるのでしょうか?
DbC(Design by Contract) と呼ばれる設計手法があります.(See
オブジェクト指向入門 by Bertrand Meyer)
メソッドの呼び出しを,呼び出し側と呼ばれる側の契約と捉えま
す.メソッドの責任は,呼び出し側が事前条件を満たせば,事後条
件を満たす.というものです.それぞれの条件は,それぞれメソッ
ドの開始前および終了後の assert で書くことができます.
class IntStack {
int itemCount;
int item[];
//...
public int pop() {
assert(0 < itemCount); // 事前条件
// pop
}
public void push(int value) {
// push
assert(!this.isEmpty()); // 事後条件
assert(this.contains(value)); // 事後条件
}
こうすることで,
1) ドキュメントより信頼できるメソッドの仕様を記述できます.
2) 不具合を切り分けることができます.(事前条件に引っかかれば
呼び出し側の契約不履行,事後条件に引っかかればメソッドの契約
不履行)
言語によっては他にも,継承のセマンティクスの強化(Liskov 則の
ランタイムチェック),synchronization (事前条件不成立ならブ
ロック),ドキュメントへの反映などなど,に利用されます.
さて,ここまでが前置き.
以下,今回の仕様追加により,楽になった部分を.
1つめ.
Java には,assert が言語に括り付けられていなかったため,これ
まで,Assert クラスを作って,
Assert.assert(condition);
とか,UnitTest などでは,TestCase extends Assert,
MyTestCase extends TestCase などとして,テストケース側に
assert を書いていました.
こういう Assert クラスを作成する手間がなくなる.
2つ目は,パフォーマンス.
class Assert {
private boolean debug = on;
static void assert(condition) {
if (on && !condition)
throw new Error();
}
}
という具合に書いた場合,debug = false に設定しても,呼び出し
側のコードにパフォーマンスの負担ががかかります.できれば,
C 言語の #ifdef debug みたいにしたい.すなわち,
pop() {
Assert.assert(...);
// ...
}
は,debug の on/off に関わらず static method 呼び出しのペナ
ルティを負っていました.これが,assertが,構文糖として提供さ
れるため,
pop() {
if ($assertionEnabled) {
// Assertion の thow
}
}
と展開され,コンパイラによってコンパイル時に assert をすっぱ
りバイトコードから消せます.
# There's no harm in asking ;-)
以上