java之assert关键字用法案例详解
作者:杨家昌 发布时间:2022-07-10 23:01:32
Java2在1.4中新增了一个关键字:assert。在程序开发过程中使用它创建一个断言(assertion)。,它的语法形式有如下所示的两种形式:
1、assert condition;
这里condition是一个必须为真(true)的表达式。如果表达式的结果为true,那么断言为真,并且无任何行动
如果表达式为false,则断言失败,则会抛出一个AssertionError对象。这个AssertionError继承于Error对象,
而Error继承于Throwable,Error是和Exception并列的一个错误对象,通常用于表达系统级运行错误。
2、asser condition:expr;
这里condition是和上面一样的,这个冒号后跟的是一个表达式,通常用于断言失败后的提示信息,说白了,它是一个传到AssertionError构造函数的值,如果断言失败,该值被转化为它对应的字符串,并显示出来。
用一个例子说明一下:
public class Test {
public static void main(String[] args) {
System.out.println("start");
assert true;
System.out.println("go on");
assert false:"stop";
System.out.println("end");
}
}
这里有一个测试类,通过之前简单的语法介绍后,可以这样简单的理解这个例子:
当程序运行到assert true这一句时,condition为true,系统会继续执行下去。而后执行到 assert false:"stop"的时候,由于condition=false,系统会抛出AssertionError。
但是试试上是不是这样的呢?
看看运行结果就知道了
start
go on
end
这个运行结果和我们一开始的预期不一致,问题出在哪里了?
原来java的断言与C语言中的断言还有有些不同的地方。
Java的assertion的开启也和C语言不太一样,在C语言中,assertion的开启是在编译时候决定的。当我们使用debug方式编译程序时候,assertion被开启,而使用release方式编译时候,assertion自动被关闭。 而Java的assertion却是在运行的时候进行决定的。其实,这两种方式是各有优缺点。如果采用编译时决定方式,开发人员将处理两种类型的目标码,debug版本和release版本,这加大了文档管理的难度,但是提高了代码的运行效率。 Java采用运行时决定的方式,这样所有的assertion信息将置于目标代码 中,同一目标代码可以选择不同方式运行,增强目标代码的灵活性,但是它将牺牲因为assertion而引起一部分性能损失。
说直白一点就是:assert关键字需要在运行时候显式开启才能生效,否则你的断言就没有任何意义。
如果需要观察断言的运行情况,就需要打开系统类的assertion功能 ,我们可使用-esa参数打开,使用 -dsa参数关闭。 -esa和-dsa的全名为-enablesystemassertions和 -disenablesystemassertions,全名和缩写名有同样的功能。
我们还是用刚刚那个测试方法,再执行试试看:
当我们只是通过java命令编译、执行测试方法时,并没有执行assert语句;然而通过java -ea Test命令显示打开assertion功能后,发现系统确实执行了assert语句。
另外,我们注意到体统抛出的是AssertionError,作为Error的一个子类,而不是 RuntimeException。Error代表一些异常的错误,通常是不可以恢复的,而 RuntimeException强调该错误在运行时才发生的特点。AssertionError通常为非常关键的错误,这些错误往往是不容易恢复的,而且assertion机制也不鼓励程序员对这种错误进行恢复。
通过这个实验的现象,可以引发一些思考:
1.assert需要显示的开启生效才有作用。
这就意味着你如果使用IDE工具编码,调试运行时候会有一定的麻烦,因为基本上java IDE都是没有开启断言功能的。并且,对于Java Web应用,程序代码都是部署在容器里面,你没法直接去控制程序的运行,如果一定要开启-ea的开关,则需要更改Web容器的运行配置参数。这对程序的移植和部署都带来很大的不便。
2.assert断言失败将面临程序的退出。这在一个生产环境下的应用是绝不能容忍的。一般都是通过异常处理来解决程序中潜在的错误。但是使用断言就很危险,一旦失败系统就挂了。
3.即使处理了Error,如果断言的代码嵌入到业务流程中,一旦assert失效,也就改变了正常的业务逻辑(如果condition中加入了赋值等操作)。
我想可能就是这些原因导致平时的java开发中几乎不会用到assert关键字,即便如此,JDK中还是存在不少使用assert的地方,比方说java.util.Locale类等
4.是不是可用通过封装一些方法,自己来完成断言的功能,既使用简单,又方便理解。至少我是这样做的。
来源:https://blog.csdn.net/yangjiachang1203/article/details/52351880
猜你喜欢
- 最近学习了一下seata,由于nacos现在也挺火,于是学习了seata注册到nacos,然后集成springcloud1.nacos配置(
- 抽象类什么是抽象类呢?在现实生活中,我们说“人类”,我们无法对应到具体某个人,同样的,&ld
- Java InputStream的任意拷贝有时候,当我们需要多次使用到同一个InputStream的时候如何实现InputStream的拷贝
- 简介:gateway主要是做路由 负载,过滤 主要是替代zuul 1.x 性能比zuul好 zuul是基于Servlet ,gateway是
- 本文基于jdk1.8进行分析。ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLoc
- 前言本文主要介绍JWT的实战运用。准备工作首先我们创建一个Asp.Net的,包含MVC和WebApi的Web项目。然后使用Nuget搜索JW
- WPF中有一个DrawingContext类,该类提供了很多画法方法,例如DrawLine,DrawText,DrawRectangle等。
- 1. 前言无论是自我学习中,还是在工作中,固然会遇到与前端搭配实现分页的功能,发现有几种方式,特此记录一下。2. 先说结论分页功能直接交给前
- 背景之前在网上发现这个问题public class GenericTest { //方法一 public static <T exte
- 相关文章:Java使用POI导出Excel(一):单sheetJava使用POI导出Excel(二):多个sheet相信在大部分的web项目
- 首先,你可能会见到如下提示:File encoding is disabled because .properties file (see
- Java反射动态修改注解的某个属性值昨晚看到一条问题,大意是楼主希望可以动态得建立多个Spring 的定时任务。这个题目我并不是很熟悉,不过
- 1、 什么是WMI WMI是英文Windows Management Instrumentatio
- 我就废话不多说了,大家还是直接看代码吧~ string url = "https://cloud.soei.com.cn/smsa
- 1. 前言我在Spring Security 实战干货:内置 Filter 全解析对Spring Security的内置过滤器进行了罗列,但
- 本文实例讲解了通知Notification使用方法,此知识点就是用作通知的显示,包括振动、灯光、声音等效果,分享给大家供大家参考,具体内容如
- idea2019导入maven项目中的某些问题idea2019导入maven项目,会出现很多莫名其妙的问题,需要注意的是如果是idea201
- 本文实例讲述了C#串口通信实现方法。分享给大家供大家参考。具体方法如下:通过COM1发送数据,COM2接收数据。当COM2接收完本次发送的数
- 前言同C语言一样,Java也有断言关键字assert,它们的用法也比较相似。注意:Java的断言是从1.4版本开始的,以前的版本不支持断言。
- 其中第二级目录包含了五个预定义主键分别是:HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MA