`
lgl669
  • 浏览: 169953 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java中Assert的用法

阅读更多
java中Assert的用法
2006-12-04 08:43

//以下有部分内容引自千罗网

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得形式,当exp1false得时候,AssertionError得默认构造器会被调用,但是assert exp1:exp2这样的形式,当exp1true的时候后面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

  1. 不要再public的方法里面检查参数是不是为null之类的操作
    例如public int get(String s)
    {
    assert s != null;
    }
    如果需要检查也最好通过if s = null 抛出NullPointerException来检查
  2. 不要用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 Level5.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是否被处理。

  1.  
  2. class Base
  3. {
  4.   public void baseMethod()
  5.   {
  6.     assert      false : "Assertion failed:This is base ";// 总是assertion失败
  7.     System.out.println("Base Method");
  8.   }
  9. }
  10.  
  11. class Derived
  12.   extends Base
  13. {
  14.   public void derivedMethod()
  15.   {
  16.     assert false"Assertion failed:This is derive";// 总是assertion失败
  17.     System.out.println( "Derived Method" );
  18.   }
  19.  
  20.   public static void main( String[] args )
  21.   {
  22.     try
  23.     {
  24.       Derived derived = new Derived();
  25.  
  26.       derived.baseMethod(  );
  27.  
  28.       derived.derivedMethod();
  29.     }
  30.     catchAssertionError ae )
  31.     {
  32.       System.out.println(ae);
  33.     }
  34.   }
  35. }

运行命令 含义 结果 
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的用法
  1. 不要再public的方法里面检查参数是不是为null之类的操作
    例如public int get(String s)
    {
    assert s != null;
    }
    如果需要检查也最好通过if s = null 抛出NullPointerException来检查
  2. 不要用assert来检查方法操作的返回值来判断方法操作的结果
    例如 assert list.removeAll();这样看起来好像没有问题 但是想想如果assert 被disable呢,那样他就不会被执行了 所以removeAll()操作就没有被执行 可以这样代替
    boolean boo = list.removeAl();
    assert boo;
分享到:
评论

相关推荐

    Java陷阱之assert关键字

     在Java中,assert关键字是从JAVA SE 1.4 引入的,为了避免和老版本的Java代码中使用了assert关键字导致错误,Java在执行的时候默认是不启动断言检查的(这个时候,所有的断言语句都将忽略!),如果要开启断言...

    Java关键词assert的使用(基于IntelliJ IDEA)

    正确算法 private static int pythagorean(int x, int y) { return x * x + y * y; } 错误算法 private static int pythagorean(int x, int y) { return x * x + y * y +...assert想在IDE中使用,就必须开虚拟机选项

    java编程常用英语单词解释

    50. Iterator (java):迭代器的意思,是 Java 中的一种基本概念,用于描述迭代器的使用。 了解这些英语单词的含义,对于 Java 开发者来说是非常重要的,可以帮助他们更好地理解 Java 语言,并编写高质量的 Java ...

    junit-assert-collector:Java库扩展了JUnit的ErrorCollector类,提供了典型的JUnit样式声明方法

    junit-assert-collector 我编写的Java库是为了补充我在Savvis / CenturyLink最初开发的测试框架而开发的测试框架。 该库实质上扩展了JUnit库的org.junit.rules.ErrorCollector类,并且提供了大多数(如果不是全部)...

    JAVA--达内培训笔记

    JAVA--达内培训笔记】 1、Java之父Golsling ...11、局部变量:定义在方法中的变量 (1)先赋值后使用 (2)从定义变量的代码块开始到代码块结束 (3)在同一范围内不允许两个局部变量发生命名冲突 * * * *

    JAVA面试题最全集

    将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载 finally?再异常处理时...

    java面试宝典

    42、一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 12 43、说出一些常用的类,包,接口,请各举5 个。 12 44、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类?是否可以...

    java 面试题 总结

    子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    必须要时从Java SE API的源代码分析,了解各种语法在Java SE API中如何应用。  《Java JDK 7学习笔记》将IDE操作纳为教学内容之一,使读者能与实践结合,提供的视频教学能更清楚地帮助读者掌握操作步骤。 内容简介 ...

    Java面试宝典-经典

    46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...

    Java面试宝典2010版

    46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...

    java面试题大全(2012版)

    46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...

    assert-text:在需要时断言多行文本

    用法 var assertText = require ( 'assert-text' ) ;assertText . equal ( 'what a wonderful\n' + 'idea for the\n' + 'module' , 'what a wonderful\n' + 'idea for a\n' + 'module' ) ; 上面的示例将抛出: Error...

    java面试题

    82. 异常的使用方法 98 83. JAVA代码查错 101 83.1. 判断 101 83.2. 判断 102 83.3. 判断 102 83.4. 判断 102 83.5. 判断 102 83.6. 判断 103 83.7. 判断 103 83.8. 判断 103 83.9. 判断 104 83.10. 判断 104 83.11....

    最新Java面试宝典pdf版

    46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...

    Java面试笔试资料大全

    46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 29 47、sleep() 和 wait() 有什么区别? 30 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...

    java面试宝典2012

    46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用? 32 47、sleep() 和 wait() 有什么区别? 33 48、同步和异步有何异同,在什么情况下分别使用他们?举例说明...

Global site tag (gtag.js) - Google Analytics