论坛首页 Java企业应用论坛

我承认我没有if(xxx != null)

浏览 7875 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2010-09-08   最后修改:2010-09-24

 

昨天正在编码兴头时被项目组xx叫去,说我修改的代码出了空指针异常,还说关键的地方比如这是界面的发起部分,就应该判断是否空指针,不然过不去。我看了一下他的环境,说你没有我的数据库脚本,如果有了数据库环境,应该就不会出现这种情况,然后他就说你这个方法本来就有抛出NullPointerException的可能性,为什么调用完之后不判断呢?而且这是程序的关键部分,出了问题界面都发不起。嗯,好吧,我承认这是我的失误,随即加了if(xxx != null)判断。

对于这件事,引发了我对空指针最佳实践的思考,想必我们使用最多的方法就是在可能发生空指针异常的地方加上:if(xxx != null),每个人都对抛出空指针异常的可能性都不同,换句话说就是这种可能性很难统一和界定,如果使用这种方式,那么代码肯定奇丑难看,到处都是if(xxx != null)else…。而且else部分也不一样,要么什么都不做,要么直接返回提示错误,要么就重新赋一个默认的值。

还有种方式就是在产生return null的地方用new对象代替,这个new对象纯粹是为了防止客户类出现null,可是这样做的可读性降低了,个人认为跟脱了裤子放屁没两样。Apireturn null这种写法也比较常见,比较符合OO逻辑。

既然不能避免null,那么你就必须小心翼翼,因为你对每个对象的操作之前你都不能保证它一定是非null,除非你做了判断,Api中为了保证某些值一定不能为null时,采用这种方式:if (name == null) {throw new NullPointerException();}。那我们自己的程序能不能这样写呢?我觉得大多数java程序的现状就是,关键地方使用了if(xxx != null)判断,某些边缘没有判断,所以经常会发生空指针异常。

       好像findBugs可以找到可能发生null的地方,不知道它的建议做法是什么?面对NullPointerException,各位有没有更好的做法呢?

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

被投隐了,不过没关系,关于几点我还要说明一下,NullPointerException是一个runtimeException,它不会像车checkedException,要么让你“吞掉”,要么让你抛出,就因为它是uncheckedException,所以我们无法精确判断哪个地方会抛出NullPointerException(其实大多数时候是我们根本没有考虑)。

设计模式中有个null object模式,它的大概意思就是对领域对象继承一个null object,它里面什么都不干,代表一个无的概念,用return null object代替return null,这样就避免了NullPointerException的出现。但是个人建议还是要分场合使用,如果return null代表“这段程序不是出现异常了才返回null,而是null本身就代表了一个无的概念”,再现实一点,遍历一个person集合,查找某个person,如果没有查找到,通常我们返回null,这里,就可以用用return null object代替return null了。

 是该总结一下空指针的最佳实践了,还是从空指针产生的根源来说:

1.在应用前端,如果null的产生是一个正常的业务逻辑的分支,比如用户的输入,你并没有限制用户可以什么都不干,那么我们就应该使用if(xxx != null)判断,如果为null,我们会给用户一个提示一个对话框,而不是一大堆异常。

2.如果null的产生是应用真正走向了异常边缘,比如环境配置问题,其他前调方法的错误,那么这时就应该大胆的抛出异常,在方法的前置条件使用断言,或者统一判断可能为null的地方,如果为null就抛出NullPointerException,或者什么都不干,大胆的往前走。举一个我实际遇到的例子,方法的入口是一个复合数据结构,但这个复合数据结构是解析xml得来的,有一天,我写的xml格式不对,导致复合数据结构某些引用指向null,那么这个时候,我们就应该大胆的抛出这个异常,让我们早点发现错误的根源,而不是使用if(xxx != null)判断或者使用一个null object导致我们以为什么问题都没有发生,或者感到不对了,却找了半天的问题根源。

3.在合适的情况下,使用null object,就像前面说的,我们在返回return null的时候用return null object代替。

   发表时间:2010-09-08  
assertNotNull
0 请登录后投票
   发表时间:2010-09-08  
如果是null 仅仅只是抛出NullPointerException
对于用户来说跟不判断又有何区别
都是一异常信息


0 请登录后投票
   发表时间:2010-09-08  
责任分明
比如collections.sort方法就不判断null,因为它觉得判断null不是他的责任
0 请登录后投票
   发表时间:2010-09-08  
不能绝对化,不过,你的确是不应该判断

判断也没有什么用,也没有解决方案。还不如早把问题暴露出来。

0 请登录后投票
   发表时间:2010-09-08  
UI的validation应该判断,其它地方应该不判断,让exception抛出来吧?


好像是你们team leader不对
0 请登录后投票
   发表时间:2010-09-08  
什么都要判断那还不累死了,抛异常是正常的,关键是在合适的地方捕获异常
0 请登录后投票
   发表时间:2010-09-08  
一般需要在给页面对象或者List时,我会常常在获取对象的那个方法有个new:
List<String> list=new ArrayList();
这样无论这个方法最终有没有得到数据,这个list都不会是null的,页面判断的时候只是if(list.size()==0){//对不起没有找到相关的数据}
用null的话 一个不好 就给用户500错误(以前在项目测试前期会出现这个……)
0 请登录后投票
   发表时间:2010-09-08   最后修改:2010-09-08
assertNotNull 参见design by contract. 最完美的DBC产品莫过于XC#了

[Requires ("o != null")]
void WriteHashCode2 (object o)
{
   Console.WriteLine(o.GetHashCode());
}

void WriteHashCode3 ([NotNull] object o)
{
  Console.WriteLine(o.GetHashCode());
}
0 请登录后投票
   发表时间:2010-09-08  
页面用el表达式.
1 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics