规避空指针异常

空指针异常:

在面向对象的语言中,指针也是对象的引用。而空指针,就是指针的内容为空(也可以理解为这个指针没有指向一块内存)。由于这是一个空的指针,指向了声明类型的类的空对象,所以在应用这个对象的属性或者方法的时候,自然是错误的,也就是会报空指针异常。if语句判断不会异常,只有操作时会出异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。

如何在开发中规避空指针异常,可以从以下几点入手:

1、equals方法的使用,Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。推荐使用java.util.Objects#equals(JDK7引入的工具类)。代码如下:

public static boolean equals(Object a, Object b) {

        return (a == b) || (a != null && a.equals(b));

}

正确的示范为:

 

错误示范为:

另外代码中直接出现的含义不明的变量一定要加注释,不然一堆魔法值会让代码的可读性大大降低,只有优秀的程序员才能写出人能读懂的代码。例如下面的不规范代码,有没有感觉读起来菊花很紧。

2、对数据处理时添加必要的判空,但是需要注意的是一部分场景是不需要的,比如参数是其它系统传过来,或者其他地方获取的传过来的,99.99%都不会为空,就没有必要添加一个冗余的空判断,这种情况也基本上不会出现。另外需要定义自己的工具类,隐藏实现,体现封装/解耦的思想。尽量不要在业务代码里面直接调用第三方的工具类。这也是解耦的一种体现。如果我们不定义自己的工具类而是直接使用第三方的工具类有2个不好的地方:不同的人会使用不同的第三方工具库,会比较乱。将来万一要修改工具类的实现逻辑会很痛苦。

以最简单的字符串判空为例,很多工具库都有 StringUtils工具类,如果我们使用commons的工具类,一开始我们直接使用 StringUtils.isEmpty,字符串为空或者空串的时候会返回为true,后面业务改动,需要改成如果全部是空格的时候也会返回true,怎么办?我们可以改成使用 StringUtils.isBlank 。看上去很简单,对吧? 如果你有几十个文件都调用了,那我们要改几十个文件,是不是有点恶心?再后面发现,不只是英文空格,如果是全角的空格,也要返回为true,怎么办?StringUtils上的方法已经不能满足我们的需求了,就不好改了。

3、所有的POJO类属性必须使用包装数据类型。为什么这么要求,是因为实体类与数据库的列结果进行映射的时候,如果用基本数据类型,映射的过程中会自动拆箱,而数据库的查询结果可能是null,由于自动拆箱,用基本数据类型接收有NPE(空指针)风险。

1、Integer i = 10; //装箱

2、int t = i; //拆箱,实际上执行了 int t = i.intValue();

如果i的值为null,自动拆箱调用方法必然会报空指针异常

4、spring的bean注入失败导致空指针,参见另一篇文件spring的bean注入失败的几种原因。

  程序员都可以写出机器可以读懂的代码,只有优秀的程序员才能写出人能读懂的代码,在开发的过程中注意规避可能发生的异常,提高代码的健壮性,应该是每个程序员的一种追求。

猜你喜欢

转载自www.cnblogs.com/wanghaichao/p/9190108.html