ITEEDU

Java Gossip: 断言(Assertion)

例外是程序中非预期的错误,例外处理是在这些错误发生时所采取的措施。

有些时候,您预期程序中应该会处于何种状态,例如某些情况下某个值必然是多少,这称之为一种断言(Assertion),断言有两种情况:成立或不成立。当预期结果与实际执行相同时,断言成立,否则断言失败。

Java在JDK 1.4之后提供断言陈述,有两种使用的语法:

assert ;
assert  : ;

boolean_expression如果为true,则什么事都不会发生,如果为false,则会发生 java.lang.AssertionError,此时若采取的是第二个语法,则会将detail_expression的结果显示出来,如果是个物 件,则呼叫它的toString()显示文字描述结果。

一个使用断言的时机是内部不变量(Internal invarant)的判断,例如在某个时间点上,或某个状况发生时,您判断某个变量必然要是某个值,举个例子来说:

AssertionDemo.java
public class AssertionDemo {
	public static void main(String[] args) {
		if(args.length > 0) {
			System.out.println(args[0]);
		}
		else {
			assert args.length == 0;
			System.out.println("没有输入自变量");
		}
	}
}

在正常的预期中,数组长度是不会小于0的,所以一但执行至else区块,数组长度必然只有一个可能,就是等于0,您断言args.length==0结果 必然成立,else之中的程序代码也只有在断言成立的状况下才能执行,如果不成立,表示程序运行存在错误,else区块不应被执行,您要停下来检查程序的错 误,事实上断言主要的目的通常是在开发时期才使用。

断言功能是在JDK 1.4之后提供的,由于断言使用assert作为关键词,为了避免您以前在JDK 1.3或更早之前版本的程序使用了assert作为变量,而导致的名称冲突问题,预设上执行时是不启动断言检查的,如果您要在执行时启动断言检查,可以使用-enableassertions或是-ea自变量,例如:

 java  -ea AssertionDemo

您可以启用断言,但选择性的使用-disableassertions或-da关闭某些类别中的断言机制,例如关闭onlyfun.caterpillar.Foo类别中的断言:

 java  -ea -da:onlyfun.caterpillar.Foo AssertionDemo

或是选择性的使用-disableassertions或-da关闭某些套件中的断言机制,例如关闭onlyfun.caterpillar套件中的断言:

 java  -ea -da:onlyfun.caterpillar... AssertionDemo

另一个使用断言的时机为控制流程不变量(Control flow invariant)的判断,例如在使用switch时,假设您已经列出了所有的可能常数:

...
switch(var) {
	case Constants.Con1:
	...
	break;
	case Constants.Con2:
	...
	break;
	case Constants.Con3:
	...
	break;
	default:
	assert false : "非定义的常数";
}
...

假设您已经在switch中列出了所有的常数,即var不该出现Constants.Con1、Constants.Con2、 Constants.Con3以外的常数,则如果发生default被执行的情况,表示程序的状态与预期不符,此时由于assert false必然断言失败。

总结就是,断言是判定程序中的某个执行点必然是某个状态,所以它不能当作像if之类的判断式使用,简单的说它不应是程序执行流程的一部份。