讨论一下:java断言没有实用价值
java从1.4开始引入了断言,但是默认断言的功能是不开启的,java断言的开启不同于c语言,c语言是在编译的时候加入断言的,而java断言的启用是在运行时期指定的。
由于1.4以后系统类中也有断言的使用,所以如果要开启系统类的断言需要使用java -esa,如果需要开启用户类的断言则需要java -ea。
在实际使用中,对于边界值和函数入参、返回值的校验我们一般是通过if..else来进行,除了向控制台报错之外,有可能还要使用一些应用定义的exception或者向数据库中记录一个日志,可以发出告警等等,总体来说这样做的可控性是非常强的。
java这个assert功能是个鸡肋,很难想象有谁会在系统上线的时候会在系统运行的时候加入一个-ea来开启断言,一定要这样做的后果是,如果参数越界的的话程序会抛出一个不应捕获的严重级别的Error错误,不可控也不可靠。
在开发阶段,唯一有用的地方有可能就是和testng结合使用了,可是我貌似更喜欢junit4一点,一样有annotation的强力支持,所以总结一下,java assert的出现和使用都是没有必要的。
static boolean $assertionsDisabled = !Test.class.desiredAssertionStatus();
public void method(int i) {
if (!$assertionsDisabled && !(i > 0)) throw new AssertionError("i 必需大于 0");
}
}</pre>
? 12 楼 aoliwen521 2011-03-19 我至今觉得是鸡肋。。鸡肋。。 13 楼 jackra 2011-03-20 断言如此设计本身是在运行时免除部分计算,增强效率.
在不考虑代码执行效率的情况下,是没有意义的. 14 楼 evanzzy 2011-03-20 非常有同感,除了用junit做测试的时候,其他地方还真没用过断言。 15 楼 jyslb 2011-03-20 freish 写道在涉及客户端到服务端通信中关于服务端的测试时,junit表示压力很大
不是在讨论如何用junit测试webservice,我是在说java assert的真正意义何在。
java断言的意义在于进行函数入参,返回值,或者一些条件值的判断,但是java assert的做法太过粗暴,直接就抛出一个Error,runtime的不能捕捉也不可控,考虑以下场景
1. 函数入参,返回值判断
采用if-else可以有效进行日志记录,数据库日志记录,可以选择抛出应用基本的异常,对于调用方来说可捕获,可控。
2. 接口调用,包括webservice
一般一个定义良好的系统,在接口规范中还定义了诸多错误返回(API的话有可能是应用级别的exception),我们可以通过if-else来控制返回什么错误,而不是像java assert一般搞出一个Error出来,完了啥事都没法干。
所以我感觉在程序代码中使用java assert没必要。
完了再讨论单元测试代码,没错,testng用到了java assert,不过现在junit4也有annotation,在单元测试的范畴里面我干嘛还用testng呢?
看了楼上诸位的留言我澄清一下,junit4的断言不是jdk assert,而testng使用的是jdk定义的assert。
16 楼 jyslb 2011-03-20 可能说的太长没人愿意看,换句话问问,你们项目中,除了testng,你们在什么地方会用到java的assert,是什么理由让你选择抛出一个Error,而不是一个应用级别的错误? 17 楼 hatedance 2011-03-21 assert既然是抛出error,那么我们如果要用就得顺着这个思路用。
error一般认为是无法恢复的错误。
比如save(Object aobject){ assert aobject !=null: "null object";...}
这关乎设计策略。到底保存一个空对象是允许的,还是禁止的。
也许我们大多数实际情况下,根本不区分excepion和error,就像南方人不区分后鼻音和前鼻音,所以,我们只用到exception就满足了。
或者我们不敢抛出error,一味抛出可捕获的excepion,怕error就把程序结束了。 18 楼 抛出异常的爱 2011-03-22 error......
谁允许你们在正式环境下开启断言了?
C语言老师教的么?
断言是为了在开发过程中定位开发错误问题
在没有ide 的 debug之前想要定位错误
log是没有办法的办法
assert是先进的生产动力.
现在这个assert感念用在了测试上
从源码中剥离出来了.
还可以不用停止在第一个错误之上