java调试技巧----assert断言的使用

刚开始大家在程序中出错的时候,尤其是逻辑错误时,都喜欢system.out.println();来输出程序的变量状态,并用if-else控制,然后等找到错误之后再把这些添加进去的语句删掉,之后发现错误又把这些语句加上…如此反复,感觉调试真的很累。

那java中都有什么可以方便调试呢?

其实java中有很多调试的特性。这里就介绍一下断言:

假设这样的情况:比如要写一个除法的运算方法,使用的时候必须要确保除数不能为0,否则程序会出错。所以我们在调用的时候一定要提供一个非0除数,然而,我们还是希望进行检查,避免出现除0的错误。我们可能会想用异常处理这个情况:

1  if(x==0) throw new IllegalArgumentException();

 

但这句话会一直留在程序中,即使我们测试完毕确定一定不会有0参与运算,代码也不会消失,除非我们手动的去删除它。如果不删除,程序中又有很多这种代码,在一定程度上会减慢程序的运行。

在Java SE 1.4中引入了关键字assert,这种断言机制允许在测试的时候向代码中插入一些检查语句,代码发布后,这些语句会自动的被类加载器跳过,所以不会降低运行的速度。

下面是断言的一个例子:

 1 import java.util.*;
2 public class TestAssert{
3 public static void main(String[] args){
4 System.out.println("Input two integers");
5 Scanner scan = new Scanner(System.in);
6 int a = scan.nextInt();
7 int b = scan.nextInt();
8 assert b!=0 : "b==0";
9 System.out.println("result:"+divide(a,b));
10
11 }
12
13 public static int divide(int a,int b){
14 return (a/b);
15 }
16 }



上面的断言代码也可以改成

assert b!=0;


这样AssertionError后面的字符串将为空。

默认情况下,断言被禁用,可以使用-enableassertions或-ea启用。上述代码的运行结果为:

启用和禁用断言不必重新编译程序,这是类加载器的功能。以下是启用或禁用断言的方法:

-ea java -ea 打开所有用户类的assertion
-da java -da 关闭所有用户类的assertion
-ea: java -ea:MyClass1 打开MyClass1的assertion
-da: java -da: MyClass1 关闭MyClass1的assertion
-ea: java -ea:pkg1 打开pkg1包的assertion
-da: java -da:pkg1 关闭pkg1包的assertion
-ea:... java -ea:... 打开缺省包(无名包)的assertion
-da:... java -da:... 关闭缺省包(无名包)的assertion
-ea:... java -ea:pkg1... 打开pkg1包和其子包的assertion
-da:... java -da:pkg1... 关闭pkg1包和其子包的assertion
-esa java -esa 打开系统类的assertion
-dsa java -dsa 关闭系统类的assertion
(其中-ea和-da的全名为-enableassertions和-disenableassertions
-esa和-dsa的全名为-enablesystemassertions和-disenablesystemassertions)

但也不是任何时候都应该使用断言,从程序的运行结果可以看出,断言失败的结果是Error,也就是说是不可捕获,不可处理,不可恢复的致命的错误,所以断言的检查只能用于开发和测试阶段,这也是断言的本来目的,所以,断言应该只用在测试是阶段确定程序内部的错误位置(尤其是逻辑错误)。

另外,Java为了让程序也能够动态开启和关闭某些类和包的assertion功能,Java修该了Class和ClassLoader的实现,增加了几个用于操作assert的API。下面简单说明一下几个API的作用。java.lang.ClassLoader类中的几个相关的API: 

setDefaultAssertionStatus() //用于开启/关闭assertion

setPackageAssertionStatus()//用于开启/关闭某些包的assertion 

setClassAssertionStatus()//用于开启/关闭某些类的assertion 

clearAssertionStatus()//用于关闭assertion

posted @ 2012-03-31 10:35  sheling  阅读(884)  评论(0编辑  收藏  举报
我的最近博客 http://blog.iyestin.com