Java陷阱之assert关键字

一、概述

在C和C++语言中都有assert关键,表示断言。

在Java中,同样也有assert关键字,表示断言,用法和含义都差不多。

二、语法

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

assert关键字语法很简单,有两种用法:

1、assert

如果为true,则程序继续执行。

如果为false,则程序抛出AssertionError,并终止执行。

2、assert :

如果为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能给你带来多少好处,多少麻烦,这是我们选择是否使用的的原则。

============================================================

comment:

反过来说,在某些开源组件中,比如validator、junit中,判断过程仿佛使用了断言风格,很有可能使用了大量的断言,但笔者在没看源码之前不能确定。

如果是开发阶段的简单测试,junit就是一个便捷强悍的工具,没有理由自己写断言而不去用它。

============================================================

comment:

首先可以用在单元测试代码中。junit侵入性是很强的,如果整个工程大量的代码都使用了junit,就难以去掉或者是选择另外一个框架。如果单元测试代码 很多,并且想复用这些单元测试案例,应该选择assert而不是junit,便于使用别的单元测试框架,比如TestNG。同理正式的功能代码根本就不应 该出现Junit,应该使用assert.

assert主要适合在基类,框架类,接口类,核心代码类,工具类中。换言之,当你的代码的调用者是另外一个程序员写得业务代码,或者是另外一个子系统时,就很有必要使用它。比如你做了一个快速排序的算法

public static List quickSort(List list){

assert list != null;

// 申请临时空间

//开始排序

for(int i : list){

//

}

}

种情况下,如果不检查传入参数的正确性,会抛出一个莫名其妙的空指针错误。你的调用者可能并不清楚你代码的细节,在一个系统的深处调试一个空指针错误是很

浪费时间的。就应该直接明确的告诉你的调用者是传入的参数有问题。否则他会怀疑你的代码有BUG。使用assert可以避免两个程序员之间互相指责对方写

的代码有问题。

assert适用那些你知道具体是什么错误,你和你的调用者已经约定应该由你的调用者去排除或检查的错误。你通过一个断言

告诉你的调用者。assert不适用那些外部系统造成的错误,比如用户输入数据的错误,某个外部文件格式错误。这些错误不是你的调用者而是用户造成的,甚

至于不属于异常,因为出现输入错误和文件格式错误是经常的,这些错误应该由业务代码去检查。

assert比较适合于被频繁调用的 基类,框架代码,工具类,核心代码,接口代码中,这正是它在运行时被去掉的原因。测试代码应该在测试阶段开启-ea参数,便于对系统深处的核心代码做仔细的测试。

Java较少使用assert的原因是Java有很完整的OO体系,强制类型转换出现得较少,所以不需要类似c那样需要频繁的检查指针的类型是否正确,指针是否为空。同时Java也很少直接管理内存或缓冲区,所以不需要频繁的检查传入的缓冲区是否为空或者是已经越界。

但使用好assert有助于提高框架代码的正确性和减少框架代码的使用者的调试时间。

===============================================================

comment:

assert要达到的目的是让程序员方便的发现自己的逻辑错误,并且不影响程序的效率。assert所发现的错误,是完全不应该出现的,是不能用异常代替的。异常,那是系统所允许的,或者是系统不可控的“错误”,它不是程序员的逻辑问题。

assert应该是开发阶段打开,而在发布后关闭。

java assert false_Java陷阱之assert关键字相关推荐

  1. java assert语句未执行_Java陷阱之assert关键字

    转自:http://lavasoft.blog.51cto.com/62575/43735/ Java陷阱之assert关键字 一.概述 在C和C++语言中都有assert关键,表示断言. 在Java ...

  2. Java基础の乱弹琴一:assert关键字

    一.概述 assert:表示断言 二.语法 在Java中,assert关键字是从JAVA SE 1.4 引入的,为了避免和老版本的Java代码中使用了assert关键字导致错误,Java在执行的时候默 ...

  3. Java 中的 断言 (assert)—— 初识 简单的使用和理解~只要这一篇就够了

    首先老样子,三个方面来理解 断言是个啥(尝试初步<理解>) 如何使用(到底咋子个用,啥时候用) 个人的思考理解和总结(说话不负责时间) 断言与if的区别 断言和异常的区别 总结 新年快乐! ...

  4. Java基础笔记(2) 程序入口 关键字 标识符 常量 变量

    提醒:关于那些和我一样新鸟来看资料的,能看懂多少看多少,看不懂的就是不重要,重要的你想我自己学习肯定要标注的,这些信息明白每个知识点实际作用就好了,其他的比如等会讲的常量内存,常量池这些都是我找的资料 ...

  5. JAVA的异常(四):finally关键字

    JAVA的异常(四):finally关键字 finally代码块:定义一定执行的代码 通常用于关闭资源 finally只有一种情况不执行,就是执行了System.exit(0)的时候,是系统退出,JV ...

  6. junit4 assert类中的assert方法总结

    junit中的assert方法全部放在Assert类中,总结一下junit类中assert方法的分类. 1.assertTrue/False([String message,]boolean cond ...

  7. Java中的synchronized与volatile关键字

    原文出处:http://hukai.me/android-training-course-in-chinese/performance/smp/index.html Java中的"synch ...

  8. python断言assert实例_Python断言assert的用法代码解析

    在开发一个程序时候,与其让它运行时崩溃,不如在它出现错误条件时就崩溃(返回错误).这时候断言assert 就显得非常有用. python assert断言是声明布尔值必须为真的判定,如果发生异常就说明 ...

  9. java线程同步——条件对象+synchronized 关键字

    [0]README 0.1) 本文描述转自 core java volume 1, 源代码为原创,旨在理解 java线程同步--条件对象+synchronized 关键字 的相关知识: 0.2)for ...

最新文章

  1. 2022-2028年中国动力电池行业深度调研及投资前景预测报告
  2. 【Python3_基础系列_006】Python3-set-集合
  3. windows下备份mysql 数据库
  4. Beyond Compare 怎么新增与卸载文件格式
  5. 算法十大排序(含动图)
  6. 腾讯云dts使用注意事项
  7. MySQL删除重复数据
  8. 计算机音乐与制谱,电脑音乐编辑、制谱与视唱练耳一本通
  9. Segger Embedded Studio使用有什么技巧?
  10. noi linux 比赛使用哪个编译器,2020NOI考题及答案
  11. SSL VPN 与 IPsec VPN
  12. 千呼万唤始出来,犹抱琵琶半遮面-go语言初识
  13. 【正向偏置和反向偏置的区别】
  14. IEEE 802.15.4协议完整中文版(4)
  15. Hadoop常用命令参数介绍
  16. hive小文件处理方法
  17. 知识点滴 - 关于汉语学习的网络资源
  18. django之restframework使用 (三)组件
  19. 16-GuliMall ElasticSearch安装分词器
  20. 基于Nodejs的外卖点餐平台的设计和实现

热门文章

  1. dovecot MySQL配置_postfix+mysql+dovecot
  2. 2018年度托福考情分析——写作篇
  3. 人工智能计算器AI Calculator 3.3.0 详细破解思路教程
  4. ModbusTCP报文
  5. 第六届蓝桥杯软件类c/c++B组决赛
  6. iOS json解析 和生成json串
  7. opencv打卡66: 方向梯度直方图(HOG)第一步:梯度幅值・梯度方向
  8. iOS8最新谍照曝光新特性PP帮手抢先看
  9. FarPoint 表格(居中)自适应显示图片
  10. 计算机科学实验班高考线,北京工业大学计算机科学与技术(实验班)专业2016年在吉林理科高考录取最低分数线...