`
cantellow
  • 浏览: 847399 次
  • 性别: Icon_minigender_1
  • 来自: 草帽海贼团
社区版块
存档分类
最新评论

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

    博客分类:
  • Java
 
阅读更多

 

昨天正在编码兴头时被项目组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代替。

分享到:
评论
8 楼 ray_linn 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());
}
7 楼 luciferdevil 2010-09-08  
一般需要在给页面对象或者List时,我会常常在获取对象的那个方法有个new:
List<String> list=new ArrayList();
这样无论这个方法最终有没有得到数据,这个list都不会是null的,页面判断的时候只是if(list.size()==0){//对不起没有找到相关的数据}
用null的话 一个不好 就给用户500错误(以前在项目测试前期会出现这个……)
6 楼 ywlqi 2010-09-08  
什么都要判断那还不累死了,抛异常是正常的,关键是在合适的地方捕获异常
5 楼 鱼言风语 2010-09-08  
UI的validation应该判断,其它地方应该不判断,让exception抛出来吧?


好像是你们team leader不对
4 楼 mathfox 2010-09-08  
不能绝对化,不过,你的确是不应该判断

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

3 楼 paranoid945 2010-09-08  
责任分明
比如collections.sort方法就不判断null,因为它觉得判断null不是他的责任
2 楼 qianhd 2010-09-08  
如果是null 仅仅只是抛出NullPointerException
对于用户来说跟不判断又有何区别
都是一异常信息


1 楼 鱼言风语 2010-09-08  
assertNotNull

相关推荐

    基于Qt的读取配置文件

    = NULL){ strRet = m_iniFile-&gt;GetValue("moonlightService", "DIPAddr"); } 4.最后在析构函数记得再判断释放这个碎片化的堆空间(严谨做法) 举例: if (m_iniFile != NULL){ delete m_iniFile; m_...

    图片文件上次,获取图片文件实际类型

    if (null != bis) { bis.close(); } if (null != fis) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } return true; } /** * ...

    可以读取EXCEL文件的js代码宣贯.pdf

    = null || excelWorkBook != undefined) { excelWorkBook.Close(); } if (excelApp != null || excelApp != undefined) { excelApp.Application.Quit(); excelApp = null; } } } ``` 这段代码首先创建了一个...

    多种方法使用java空指针功能.docx

    =`运算符可以安全地用于比较`null`,但`&gt;`、`等运算符会因为无法对`null`进行计算而抛出异常。 #### 4. `xxx == null`与`null == xxx`的等价性 在Java中,`xxx == null`与`null == xxx`是等价的,并且无论哪种写法...

    在View中显示“您好,我是XXX文本在View内自左向右循环滚动

    1.在View中显示“您好,我是XXX!”。 2.文本在View内自左向右循环滚动; 3.文字在红、蓝、绿、黄四种颜色之间周期变化。红(255,0,0)蓝(0,255,0)绿(0, 0,255)黄(255,255,0);

    循环列队数据结构课题舞会配对的问题

    = NULL) && (bSrc != NULL)); char* address = aDest; while ((*aDest++ = *bSrc++) != '\0') NULL; return address; } ``` **说明:** 该函数用于将一个字符串复制到另一个字符串中。 #### 2. 字符串比较 `...

    关于System.Convert的那些事儿

    =null && Convert.ToBoolean(obj)==true){ //Do something}上面的代码的意图很明显,先判断obj 是不是null,如果不是null 的话,再调用Convert.ToBoolean方法,判断是不是True。 上面的方法没有任何问题,但有一点...

    c#和net存取cookies操作示例

    = null && Request.Cookies[strName].Values[subKey] != null) return Server.HtmlEncode(Request.Cookies[strName][subKey].Value); else return null; } } ``` 使用这个类,你可以在应用程序中方便地调用`...

    vc++游戏编程指南

    3. **错误检测**:在整个初始化过程中,频繁使用`if(xxx != DD_OK)`的方式进行错误检测,确保每一步操作都正确无误。 ### 结论 通过以上内容,我们可以了解到DirectDraw在游戏开发中的重要性和基本使用流程。...

    org.apache.tools.zip解决解压乱码问题

    if (null != zos) { zos.close(); } } } /** * * 功能描述:压缩文件 * 创建者:XXX * 创建日期: 2015年5月7日 - 下午1:37:55 * 版本: V0.1 * 修改者: * 修改日期: ...

    前端大厂最新面试题-typeof_instanceof.docx

    == 'object' || left === null) return false; // getPrototypeOf 是 Object 对象自带的 API,能够拿到参数的原型对象 let proto = Object.getPrototypeOf(left); while (true) { if (proto === null) return ...

    JFileChooser使用详解.pdf

    = null && extension.equalsIgnoreCase(".png")) { return true; } } return false; } public String getDescription() { return "PNG图片"; } private String getExtension(File f) { if (f != null) { ...

    velocity为空判断

    #ifnotnull($XXX) 变量$XXX不为null #else 变量$XXX为null #endif ``` #### 方法二:`$null.isNull()` 这是一个更直接的检查方式,无需额外配置。推荐使用此方法,特别是当判断集合对象是否为null时,非常实用。...

    grpc最简单的demo案例

    if err != nil { log.Fatalf("failed to listen: %v", err) } log.Println("Server is running on port 50051...") if err := server.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } ``` 5....

    VC++ 折线图 柱状去 条形图

    我自己的VC++课程设计作业。 int k=0; srand((unsigned)time(NULL));... if(j%3!=0) { ofs(4)☆★☆★☆"; } else //三个数换行 数字后面不带符号 { printf("\n"); ofs(4); } } ofs.close();

    限制pc端访问页面的代码

    == "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1); } if (!isMobileDevice()) { alert("对不起,此页面仅支持移动设备访问。"); // 或者重定向到其他页面 window.location.href = ...

    程序问候,Hello,xxx!

    输入名字,程序就会自动问候你,是不是很神奇啊!? 那就快一点下来看看吧!!体验不一样的感觉吧!!

    Mybatis单个参数的if判断报异常There is no getter for property named 'xxx' in 'class java.lang.Integer'的解决方案

    = null and langId != null"&gt; and lang_id = #{langId} &lt;/if&gt; ``` 在这个修正后的代码中,`test`属性的条件表达式检查了`_parameter`对象是否存在(即参数不为空)以及`langId`是否不为空。当`langId`有值时,...

    ResultSet

    = null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } ``` 6. 结果集的状态:ResultSet有三种状态:未初始化、已移动到下一行和结束。调用next()会改变其状态,且一旦到达...

    高精度类(无压位),C++,基本可以像基本类型一样使用

    =,&gt;,&lt;,&gt;=,&lt;=:比较大小,第二个操作数(运算符后面那个)支持IAKIOI,int 时间复杂度,n表示第一个操作数,m表示第二个操作数: 加法:O(max(n, m)) 减法:O(max(n, m)) 乘法:O(nm),抱歉我不会 FFT。 除法:O...

Global site tag (gtag.js) - Google Analytics