一、概述
在C和C++语言中都有assert关键,表示断言。
在Java中,同样也有assert关键字,表示断言,用法和含义都差不多。
二、语法
在Java中,assert关键字是从JAVA SE 1.4 引入的,为了避免和老版本的Java代码中使用了assert关键字导致错误,Java在执行的时候默认是不启动断言检查的(这个时候,所有的断言语句都将忽略!),如果要开启断言检查,则需要用开关-enableassertions或-ea来开启。
assert关键字语法很简单,有两种用法:
1、assert <boolean表达式>
如果<boolean表达式>为true,则程序继续执行。
如果为false,则程序抛出AssertionError,并终止执行。
2、assert <boolean表达式> : <错误信息表达式>
如果<boolean表达式>为true,则程序继续执行。
如果为false,则程序抛出java.lang.AssertionError,并输入<错误信息表达式>。
三、应用实例
下面给出一个例子,通过例子说明其用法:
public class AssertFoo {
public static void main(String args[]) {
//断言1结果为true,则继续往下执行
assert true;
System.out.println("断言1没有问题,Go!");
System.out.println("\n-----------------\n");
//断言2结果为false,程序终止
assert false : "断言失败,此表达式的信息将会在抛出异常的时候输出!";
System.out.println("断言2没有问题,Go!");
}
}
保存代码到C:\AssertFoo.java,然后按照下面的方式执行,查看控制台输出结果:
1、编译程序:
C:\>javac AssertFoo.java
2、默认执行程序,没有开启-ea开关:
C:\>java AssertFoo
断言1没有问题,Go!
-----------------
断言2没有问题,Go!
3、开启-ea开关,执行程序:
C:\>java -ea AssertFoo
断言1没有问题,Go!
-----------------
Exception in thread "main" java.lang.AssertionError: 断言失败,此表达式的信息将
会在抛出异常的时候输出!
at AssertFoo.main(AssertFoo.java:10)
四、陷阱
assert关键字用法简单,但是使用assert往往会让你陷入越来越深的陷阱中。应避免使用。笔者经过研究,总结了以下原因:
1、assert关键字需要在运行时候显式开启才能生效,否则你的断言就没有任何意义。而现在主流的Java IDE工具默认都没有开启-ea断言检查功能。这就意味着你如果使用IDE工具编码,调试运行时候会有一定的麻烦。并且,对于Java Web应用,程序代码都是部署在容器里面,你没法直接去控制程序的运行,如果一定要开启-ea的开关,则需要更改Web容器的运行配置参数。这对程序的移植和部署都带来很大的不便。
2、用assert代替if是陷阱之二。assert的判断和if语句差不多,但两者的作用有着本质的区别:assert关键字本意上是为测试调试程序时使用的,但如果不小心用assert来控制了程序的业务流程,那在测试调试结束后去掉assert关键字就意味着修改了程序的正常的逻辑。
3、assert断言失败将面临程序的退出。这在一个生产环境下的应用是绝不能容忍的。一般都是通过异常处理来解决程序中潜在的错误。但是使用断言就很危险,一旦失败系统就挂了。
五、对assert的思考
assert既然是为了调试测试程序用,不在正式生产环境下用,那应该考虑更好的测试JUint来代替其做用,JUint相对assert关键的所提供的功能是有过之而无不及。当然完全可以通过IDE debug来进行调试测试。在此看来,assert的前途一片昏暗。
因此,应当避免在Java中使用assert关键字,除非哪一天Java默认支持开启-ea的开关,这时候可以考虑。对比一下,assert能给你带来多少好处,多少麻烦,这是我们选择是否使用的的原则。
以上仅仅代表我个人观点,欢迎大家留言讨论。
-----------------------------------------------------------------------------------
下面是一些Assert的例子:
assert 0 < value;
assert 0 < value:"value="+value;
assert ref != null:"ref doesn''t equal null";
assert isBalanced();
-----------------------------------------------------------------------------------
AssertinError类是Error的直接子类,因此代表程序出现了严重的错误,这种异常通常是不需要程序员使用catch语句捕捉的。
使用assert的准则:assert语句的作用是保证程序内部的一致性,而不是用户与程序之间的一致性,所以不应用在保证命令行参数的正确性。可以用来保证传递给private方法参数的正确性。因为私有方法只是在类的内部被调用,因而是程序员可以控制的,我们可以预期它的状态是正确和一致的。公有方法则不适用。此外,assert语句可用于检查任何方法结束时状态的正确性,及在方法的开始检查相关的初始状态 等等。
assert语句并不构成程序正常运行逻辑的一部分,时刻记住在运行时它们可能不会被执行。
-----------------------------------------------------------------------------------
两类参数:
参数 -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: 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
-dsajava -dsa 关闭系统类的assertion
-----------------------------------------------------------------------------------
不要再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为了让程序也能够动态开启和关闭某些类和包的assertion功能,Java修该了Class和ClassLoader的实现,增加了几个用于操作assert的API。下面简单说明一下几个API的作用。
ClassLoader类中的几个相关的API:
setDefaultAssertionStatus:用于开启/关闭assertion功能
setPackageAssertionStatus:用于开启/关闭某些包的assertion功能
setClassAssertionStatus: 用于开启/关闭某些类的assertion功能
clearAssertionStatus:用于关闭assertion功能
分享到:
相关推荐
编程语言JAVA断言使用.pdf
文档表示java中断言的使用,使用断言的好处,以及怎么使用
JAVA断言技术详解,1、What will happen when you attempt to compile and run the following code? (Assume that the code is compiled and run with assertions enabled) 1. public class AssertTest 2. { 3. ...
Selenium-java断言(90)【2021-02-02】.docx
如果你认真学习每个ppt并自己敲完这些实例,你的java基础已经很优秀了!这些资料就是某些大学和培训机构一个学期或更长时间学习的! 为的是共同学习,共同进步! 注:本资料不承担任何法律责任!
可以为Java复杂的测试提供简单的方法!可以加快开发进度
AssertJ 是 JAVA 的流畅断言库。示例代码:// unique entry point to get access to all assertThat methods and utility methods (e.g. entry) import static org.assertj.core.api.Assertions....
主要介绍了java异常处理机制示例(java抛出异常、捕获、断言),需要的朋友可以参考下
真理使您的测试断言和失败消息更具可读性。
诊断 Java 代码: Java 编程中的断言和时态逻辑 另有翻译诊断 Java 代码: Java 编程中的断言和时态逻辑 另有翻译
- "断言"*@Function:断言public class TestAssert {开启MyEclipse对断言的支持。
定义异常 使用try、catch 和 finally 语句 描述异常分类 识别普通异常 编写程序自己处理异常 使用断定 区分适当喝不适当的断定的使用 运行时屏蔽断定
Java异常和断言PPT教案学习.pptx
使用断言 使用JDK Logging 使用Commons Logging 使用Log4j 使用SLF4J和Logback 反射 Class类 访问字段 调用方法 调用构造方法 获取继承关系 动态代理 注解 使用注解 定义注解 处理注解 泛型 什么是...
CoreJava DAY15 异常、断言 52 CoreJava DAY16 反射、注释 57 CoreJava DAY17 GUI 64 CoreJava DAY18 awt event 81 CoreJava DAY19-20 多线程 85 CoreJava DAY21-22 IO 95 CoreJava DAY23 网络编程 107
全量断言方法-Java版 /** * 校验结果的每一个值 * * @param exp * @param map */ private void checkEveryResultInfo(Map, Object> exp, Map, Object> map) { for (Map.Entry, Object> m : exp.entrySet()) {...
主要介绍了java接口自动化测试框架及断言详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
主要介绍了Java异常处理中断言的使用,是Java入门学习中的基础知识,需要的朋友可以参考下
单元测试 JUnit 断言 注解 mock Unitils spring 注解