本文来自《Java核心技术》
为什么需要断言
比如你想要假设某个条件符合的时候再来进行从操作,比如数值为非负或者文件存在又或者字符串不为空,我们可以用判断语句,如果条件不满足的时候,可以抛出异常。这样做似乎没什么问题,但是,如果这样的语句太多了的话就会充斥在代码当中,而且会导致程序的执行速度变慢。如果只是测试时需要,而发布时又不需要,那么这些代码是去不掉的,这个时候断言就起作用了。
什么是断言
断言机制允许在测试的期间向代码中插入一些查询语句。当代码发布时,这些插入的检测语句将会被移走。
断言使用形式
java中引入了关键字assert。
- assert 条件;
- assert 条件:表达式;
这两种形式都会对条件进行检测,如果结果为false,则抛出一个AssertError异常。在第二种形式中,表达式将被传入AssertionError的构造器,并装换成一个消息字符串。
表达式部分的唯一目的就是产生一个消息字符串。AssertionError对象并不存储表达式的值,因此,不可能在以后得到它。
JDK文档中描述的是:如果使用表达式的值,就会鼓励程序员试图从断言中恢复程序的运行,这不符合断言机制的初衷。
启用和禁用断言
在默认情况下,断言是被禁用的。可以在程序运行时用-enableassertions
或-ea
选项启用它:
java -enableassertions MyApp
启用或者禁用断言不必重新编译程序。启动或者禁用断言是类加载器的功能。当断言被禁用时,类加载器将跳过断言代码,因此,不会降低程序的运行速度。
也可以在某个类或者某个包中使用断言,例如:
java -ea:MyClass -ea:com.mycompany.mylib... MyApp这条命令将开启MyClass类以及在com.mycompany.mylib包和它的子包中的所有类的断言。选项-ea将开启默认包中的所有类的断言。
也可以使用-disableassertions或-da禁用某个特定的类和包的断言:
java -ea:... -da:MyClass MyApp有些类不是由类加载器加载,而是直接由虚拟机加载。可以使用这些开关有选择地启用或禁用哪些类中的断言。
然而,启用和禁用所有断言的-ea和-da开关并不能应用到那些没有类加载器的“系统类”上。对于这些系统类而言,需要使用-enablesystemassertions/-esa开关启动断言。使用断言完成参数检查
java中的3中处理系统错误的机制:
- 抛出一个异常
- 日志
- 使用断言
什么时候应该使用断言呢?
- 断言失败是致命的、不可恢复的错误
- 断言检查只用于开发和测试阶段
因此,不应该使用断言向程序的其他部分通告发生了可恢复性的错误,或者,不应该作为程序向用户通告问题的手段。断言只应该是在测试阶段确定程序内部错误的位置。
断言是一种测试和调试阶段所使用的战术性工具;而日志记录是一种在程序的整个生命周期都可以使用的策略性工具。
public class App { public static void main( String[] args ) { int a = -1; assert a > 0 : "liuni是笨蛋"; System.out.println( "Hello World!" ); }}