Java的断言机制assert是一种用于测试阶段的语法特性,它允许我们在测试期间向代码中插入一些检查语句。代码发布时这些检测语句将被自动移除。
断言关键字assert有下列两种形式
当结果为false时,会抛出一个AssertionError
异常。在第二种形式中,表达式将被传入异常的构造器,构造出你想要的一种消息字符串。
注意这个消息字符串仅在这个时候被创建并跟随异常展示出来,而不能以任何方式被保存。因为如果保存为一个内存中的变量,意味着断言机制可能脱离测试环境而影响到代码的真实运行。
例如,我们要断言x是一个正数,只需要使用以下形式。
assert x > 0;
也可以将x的值传递给异常构造器,从而显示。
assert x > 0 : x;
默认情况下断言被禁用,可以在运行程序时用-enableassertions
或-ea
这两个参数中的一个来启用。
启用和禁用断言时不需要重新编译程序,因为启用和禁用断言是类加载器的功能,而类加载器在解释字节码阶段运行。
也可以在某个类或者整个包中使用断言,如
java -ea:MyClass -ea:com.pedro.src... MyApp
这段代码将开启MyClass
类以及com.pedro.src
包和它的所有子包中的断言。
也可以用选项-disableassertions
或-da
禁用某个特定类和包的断言
java -ea:... -da:MyClass MyApp
使用断言有两个需要注意的条件
例如我们有一个方法签名
static void sort(int[] array,int x,int y){ ... }
我们希望拒绝null数组调用这个方法,那我们应该这样做。
static void sort(int[] array,int x,int y){ assert a != null; ... }
这样的在方法开头检查参数的形式我们称为前置条件。
以下是一段示例代码,我们试图用注释的方式说明一个if-else分支中的假设。
if (i X 3 == 0) ... else if (i X 3 = 1) ... else // (i % 3 == 2) ...
我们也可以用断言做这件事
if (i X 3 == 0) ... else if (i X 3 = 1) ... else assert i % 3 == 2; ...
但是实际上,如果我们是经验丰富的工程师,我们应该会考虑到i
可能是一个负值,所以最好在 if 语句之前使用另一个断言。
assert i >= 0; if (i X 3 == 0) ... else if (i X 3 = 1) ... else assert i % 3 == 2; ...