assert 语句用来验证 Java 代码的设计假想。断言(assertion)由 assert 关键字和布尔表达式组成,程序员认为布尔表达式的计算结果始终应该为 true。默认情况下断言未启用,assert 语句什么作用也没有。
不过,可以启用断言,作为一种调试工具。启用后,assert 语句会计算表达式。如果表达式的计算结果确是 true,assert 语句什么也不做;如果计算结果是 false,断言失败,assert 语句抛出 java.lang.AssertionError 异常。
在 JDK 库之外,极少使用 assert 语句。用它测试大多数应用都不灵便,一般的开发者很少使用,不过有时用来现场调试复杂的多线程应用。
assert 语句可以包含可选的第二个表达式,使用冒号和第一个表达式分开。如果启用了断言,而且第一个表达式的计算结果为 false,那么第二个表达式的值会作为错误代码或错误消息传给 AssertionError() 构造方法。assert 语句的完整句法如下:
assert assertion;
或者:
assert assertion : errorcode;
为了有效使用断言,必须注意几处细节。首先,要记住,一般情况下程序没有启用断言,只有少数情况才会启用。这意味着,编写断言表达式时要小心,不能有副作用。
注意:绝不要在自己编写的代码中抛出 AssertionError 异常,如果这么做,可能会在 Java 平台未来的版本中得到意料之外的结果。
如果抛出了 AssertionError 异常,表明程序员的假想之一没有实现。这意味着,在设计的使用范围之外使用了代码,无法正常运行。简单来说,没有看似合理的方式能从AssertionError 异常中恢复,因此不要尝试捕获这个异常(除非在顶层简单捕获,以对用户更友好的方式显示错误)。
启动断言
为了效率,不应该在每次执行代码时都测试断言,因为 assert 语句认为假想始终为真。因此,默认情况下禁用了断言,assert 语句没有作用。不过,断言代码还是会编译到类文件中,所以需要诊断或调试时可以启用断言。断言可以全局启用,也可以把命令行参数传给Java 解释器,有选择性地启用。
如果想为系统类之外的所有类启用断言,使用 -ea 参数。如果想为系统类启用断言,使用-esa 参数。如果想为某个具体的类启用断言,使用 -ea 参数,后跟一个冒号和类名:
java -ea:com.example.sorters.MergeSort com.example.sorters.Test
如果想为包中所有的类和子包启用断言,在 -ea 参数后面加上冒号、包名和三个点号:
java -ea:com.example.sorters... com.example.sorters.Test
禁用断言
使用 -da 参数,通过相同的方式可以禁用断言。例如,为整个包启用断言,但在某个类或子包中禁用,可以这么做:
java -ea:com.example.sorters... -da:com.example.sorters.QuickSort
java -ea:com.example.sorters... -da:com.example.sorters.plugins..
最后,类加载时可以控制是否启用断言。如果在程序中使用自定义的类加载程序,而且想启用断言,可能会对这些方法感兴趣。