您的位置:首页 > 编程语言 > Java开发

java中Assert的用法

2016-09-07 15:41 429 查看
assert是在J2SE1.4中引入的新特性,assertion就是在代码中包括的布尔型状态,程序员认为这个状态是true。一般来说assert在开发的时候是检查程序的安全性的,在发布的时候通常都不使用assert。在1.4中添加了assert关键字和j

assert是在J2SE1.4中引入的新特性,assertion就是在代码中包括的布尔型状态,程序员认为这个状态是true。一般来说assert在开发的时候是检查程序的安全性的,在发布的时候通常都不使用assert。在1.4中添加了assert关键字和java.lang.AssertError类的支持。

首先,我们有必要从一个例子说起assert

public class AssertTest

{

public static void main(String[] args)

{

AssertTest at = new AssertTest();

at.assertMe(true);

at.assertMe(false);

}

private void assertMe(boolean boo)

{

assert boo?true:false; 

System.out.println("true condition");

}

}

程序中包含了assert的话,你要用javac -source 1.4 xxx.java来编译,否则编译器会报错的。要想让assert得部分运行的话,要使用java -ea xxx来运行,否则包含assert得行会被忽略。下面我们运行

javac -source 1.4 AssertTest.java 

java -ea AssertTest

看看结果的输出是:

true condition

Exception in thread "main" java.lang.AssertionError

at AssertTest.assertMe(AssertTest.java:13)

at AssertTest.main(AssertTest.java:7)

当我们运行at.assertMe(true)得时候,由于assert boo?true:false相当于 assert true;因此没有任何问题,程序往下执行打印出true condition,但是执行at.assertMe(false)的时候相当于assert false,这个时候解释器就会抛出AssertionError了,程序就终止了。大家必须清楚AssertionError是继承自Error得,因此你可以不再程序中catch它的,当然你也可以在程序中catch它然后程序可以继续执行。例如:

public class AssertTest

{

public static void main(String[] args)

{

AssertTest at = new AssertTest();

try

{

at.assertMe(true);

at.assertMe(false);

}

catch(AssertionError ae)

{

System.out.println("AsseriontError catched"); 

}

System.out.println("go on");

}

private void assertMe(boolean boo)

{

assert boo?true:false; 

System.out.println("true condition");

}

}

assert还有另外一种表达的方式,就是assert exp1:exp2;其中exp1是个boolean返回值得表达式,而exp2可以是原始的数据类型或者对象都可以例如:

boolean boo = true;

String str = null;

assert boo = false:str="error";

我们刚开始讲得assert exp1得形式,当exp1是false得时候,AssertionError得默认构造器会被调用,但是assert exp1:exp2这样的形式,当exp1为true的时候后面exp2被或略,如果false的话,后面的表达式的结果会被计算出来并作为AssertionError得构造器参数。看下面的例子:

public class AssertTest

{

public static void main(String[] args)

{

AssertTest at = new AssertTest();

at.assertMe(true);

at.assertMe(false);

}

private void assertMe(boolean boo)

{

String s = null;

assert boo?true:false:s = "hello world"; 

System.out.println("true condition");

}

}运行的时候会得到这样的结果

true condition

Exception in thread "main" java.lang.AssertionError: hello world

at AssertTest.assertMe(AssertTest.java:14)

at AssertTest.main(AssertTest.java:7)

Assert最好不要滥用,原因是assert并不一定都是enable的,下面两种情况就不应该用assert

不要再public的方法里面检查参数是不是为null之类的操作

例如public int get(String s)

{

assert s != null;

}

如果需要检查也最好通过if s = null 抛出NullPointerException来检查 

不要用assert来检查方法操作的返回值来判断方法操作的结果 

例如 assert list.removeAll();这样看起来好像没有问题 但是想想如果assert 被disable呢,那样他就不会被执行了 所以removeAll()操作就没有被执行 可以这样代替

boolean boo = list.removeAl();

assert boo;

eclipse 中怎样设置 参数来 使用 Asset

       依次进入eclipse的菜单项Window -> Preferences -> Java -> Compiler -> Compliance and Classfiles

     将Compiler Compliance Level to 5.0.

       断言在java的JDK1.4版本中添加进来,这个设置告诉编译器识别和允许断言语句,但是还没有开启断言。

      接下来,进入菜单项Window -> Preferences -> Java -> Compiler -> Compliance and Classfiles,并且设置:

       Compiler Compliance Level: 5.0

    Use default compliance settings unchecked 

       Generated .class files compatibility: 5.0 

       Source compatibility: 5.0

    Disallow identifiers called 'assert': Error

    Compiler Compliance Level to 5.0

选择开启或关闭Assert功能

由于我们可以选择开启assertion功能,或者不开启,另外我们还可以开启一部分类或包的assertion功能,所以运行选项变得有些复杂。通过这些选项,我们可以过滤所有我们不关心的类,只选择我们关心的类或包来观察。下面介绍两类参数:

 

参数 -esa 和 -dsa:

它们含义为开启(关闭)系统类的assertion功能。由于新版本的Java的系统类中,也使了assertion语句,因此如果用户需要观察它们的运行情况,就需要打开系统类的assertion功能 ,我们可使用-esa参数打开,使用 -dsa参数关闭。

-esa和-dsa的全名为-enablesystemassertions和-disenablesystemassertions,全名和缩写名有同样的功能。 

参数 -ea和-ea:

它们含义为开启(关闭)用户类的assertion功能:通过这个参数,用户可以打开某些类或包的assertion功能,同样用户也可以关闭某些类和包的assertion功能。打开assertion功能参数为-ea;如果不带任何参数,表示打开所有用户类;如果带有包名称或者类名称,表示打开这些类或包;如果包名称后面跟有三个点,代表这个包及其子包;如果只有三个点,代表无名包。关闭assertion功能参数为-da,使用方法与-ea类似。

-ea和-da的全名为-enableassertions和-disenableassertions,全名和缩写名有同样的功能。

下面表示了参数及其含义,并有例子说明如何使用。

参数 例子 说明 

-ea java -ea 打开所有用户类的assertion 

-da java -da 关闭所有用户类的assertion 

-ea:<classname> java -ea:MyClass1 打开MyClass1的assertion 

-da:<classname> java -da: MyClass1 关闭MyClass1的assertion 

-ea:<packagename> java -ea:pkg1 打开pkg1包的assertion 

-da:<packagename> java -da:pkg1 关闭pkg1包的assertion 

-ea:... java -ea:... 打开缺省包(无名包)的assertion 

-da:... java -da:... 关闭缺省包(无名包)的assertion 

-ea:<packagename>... java -ea:pkg1... 打开pkg1包和其子包的assertion 

-da:<packagename>... java -da:pkg1... 关闭pkg1包和其子包的assertion 

-esa java -esa 打开系统类的assertion 

-dsa java -dsa 关闭系统类的assertion 

综合使用 java -dsa:MyClass1:pkg1 关闭MyClass1和pkg1包的assertion

其中...代表,此包和其子包的含义。例如我们有两个包为pkg1和pkg1.subpkg。那么pkg1...就代表pkg1和pkg1.subpkg两个包。

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

ClassLoader类中的几个相关的API:

  setDefaultAssertionStatus:用于开启/关闭assertion功能

  setPackageAssertionStatus:用于开启/关闭某些包的assertion功能

  setClassAssertionStatus: 用于开启/关闭某些类的assertion功能

  clearAssertionStatus:用于关闭assertion功能

最后在Run -> Run... -> Arguments菜单项的VM arguments区域,加上断言开启的标志

-enableassertions 或者-ea 就可以了。

assertion与继承

在本节,我们将考虑assertion与继承的关系,研究assert是如何定位的。如果开启一个子类的assertion,那么它的父类的assertion是否执行?

下面的例子将显示如果一个assert语句在父类,而当它的子类调用它时,该assert为false。我们看看在不同的情况下,该assertion是否被处理。

  class Base 



  public void baseMethod() 

  { 

    assert      false : "Assertion failed:This is base ";// 总是assertion失败 

    System.out.println("Base Method"); 

  } 



  

class Derived 

  extends Base 



  public void derivedMethod() 

  { 

    assert false: "Assertion failed:This is derive";// 总是assertion失败 

    System.out.println( "Derived Method" ); 

  } 

  

  public static void main( String[] args ) 

  { 

    try 

    { 

      Derived derived = new Derived(); 

  

      derived.baseMethod(  ); 

  

      derived.derivedMethod(); 

    } 

    catch( AssertionError ae ) 

    { 

      System.out.println(ae); 

    } 

  } 

}

运行命令 含义 结果 

Java Derived 不启用assertion Base Method

Derived Method 

Java -ea Derived 开启所有assertion Java.lang.AssertionError:Assertion Failed:This is base 

Java -da Derived 关闭所有assertion Base Method

Derived Method 

Java -ea:Base Derived 仅打开Base的assertion Java.lang.AssertionError:Assertion Failed:This is base 

Java -ea:Derived Derived  仅打开Derived的assertion Base Method

Java.lang.AssertionError:Assertion Failed:This is derived

从这个例子我们可以看出,父类的assert语句将只有在父类的assert开启才起作用,如果仅仅开启子类的assert,父类的assert仍然不运行。例如,我们执行java -ea:Derived Derived的时候,Base类的assert语句并不执行。因此,我们可以认为,assert语句不具有继承功能。

 

assert的用法

不要再public的方法里面检查参数是不是为null之类的操作

例如public int get(String s)

{

assert s != null;

}

如果需要检查也最好通过if s = null 抛出NullPointerException来检查 

不要用assert来检查方法操作的返回值来判断方法操作的结果 

例如 assert list.removeAll();这样看起来好像没有问题 但是想想如果assert 被disable呢,那样他就不会被执行了 所以removeAll()操作就没有被执行 可以这样代替

boolean boo = list.removeAl();

assert boo;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java assert