JAVA assert断言


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;



转载地址:https://blog.csdn.net/u014470581/article/details/52460212                (非原文地址)

侵删。


猜你喜欢

转载自blog.csdn.net/sunshine_yg/article/details/80495319