文档章节

java中的断言处理assert

900
 900
发布于 2015/11/24 10:12
字数 2183
阅读 58
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

断言机制允许在测试期间向代码中插入一些检查语句,当代码发布时,这些插入的检测语句将会被自动地移走。(怎么移?移走之后如果发生参数错误怎么处理?)

默认条件下,断言被禁用,运行时用 -enableassertions 或者 -ea启用

java -ea myapp

也可以用-da禁用某个特定类和包的断言。

1、断言失败是致命的,不可恢复的错误。

2、断言检查只用于开发和测试阶段。


转一篇assert的文章。

在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
  -dsa    java -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功能 


© 著作权归作者所有

上一篇: Spring assert
下一篇: byteUtils分享
900

900

粉丝 5
博文 18
码字总数 6054
作品 0
崇明
私信 提问
java断言机制(assert)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/Rsx/article/details/99703456 概述 断言使用的时候不是很多,测试时...

不专业得Cook
08/18
0
0
Java assert 关键字使用

关于Java assert关键字的使用,参考Stack Overflow的高票回答: What are some real life examples to understand the key role of assertions? Assertions (by way of the assert keyword) ......

Acce1erator
2017/10/18
47
0
编写高质量代码:改善Java程序的151个建议(第1章:Java开发中通用的方法和准则___建议14~20)

作为一个由影视圈转行做Java的菜鸟来说,读书是很关键的,本系列是用来记录《编写高质量代码 改善java程序的151个建议》这本书的读书笔记。方便自己查看,也方便大家查阅。 建议14:使用序列...

青衣霓裳
07/11
130
0
GUAVA--基础工具(Preconditions)

1、前置条件 俗话说丑话讲在前面,在做某些事情的时候是需要做一些前置条件的。假如需要修改一条数据的话,当参数传进来,我们要先查询这条数据是否存在。这时候就需要一个if了,如果参数还需...

MrYuZixian
11/22
18
0
JAVA 私塾第八、九章笔记整理

JAVA 私塾第八、九章笔记整理 第八章 异常和断言 一. 异常的分类 java.lang.Throwable类充当所有对象的父类,可以使用异常处理机制将这些对象超出并捕获。有Error和Exception两个基本子类。...

luodis
2011/02/15
167
1

没有更多内容

加载失败,请刷新页面

加载更多

为什么面试必问线程状态?你的回答满分了吗

看很多同学的面经、网上的面试资料,都不约而同的提到了一个基础问题:“你知道线程有几种状态吗?状态之间的扭转是怎样的?”,有准备的同学都知道有五种:New(新建)、Runnable(可运行)...

Z_J_H
29分钟前
4
0
如何保障云上数据安全?一文详解云原生全链路加密

点击下载《不一样的 双11 技术:阿里巴巴经济体云原生实践》 本文节选自《不一样的 双11 技术:阿里巴巴经济体云原生实践》一书,点击上方图片即可下载! 作者 李鹏(壮怀)阿里云容器服务高...

阿里巴巴云原生
29分钟前
3
0
获取数组的第一个元素

我有一个数组: array( 4 => 'apple', 7 => 'orange', 13 => 'plum' ) 我想获得此数组的第一个元素。 apple 预期结果: apple 一个要求: 它不能通过引用传递来完成 ,所以array_shift不是一......

javail
31分钟前
4
0
哈希情史知多少

<p align="right">——日拱一卒,不期而至!</p> 简介 hash是我们工作中经常听到的词,比如哈希表、哈希函数、hashCode、HashTable、HashMap等等,那么它们之间到底有怎样的爱恨情仇呢?来一...

彤哥读源码
37分钟前
4
0
SpringCloud 学习(5) --- Zuul(一)基本概念、配置

[TOC] Spring Cloud eureka:注册中心 服务端:提供注册 客户端:进行注册 ribbon:负载均衡(集群) Hystrix:熔断器,执行备选方案 Feign:远程调用 Zuul:网关,统一入口。 1.1、一夫当关,...

庭前云落
40分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部