NullPointException空指针异常相关及预防办法

空指针异常相关及预防办法

本文结合网上搜索和实践解决的办法整理

1.空指针异常

(实际上指的是java的引用)
简单理解:空指针就是空引用;引用本身为空,却用他调用了方法和属性
null是所有引用类型的默认值,如果没有让一个引用指向一个实际存在的对象,它的默认值就是null。
一般在定义变量的时候都会进行初始化(这也是写代码的一个良好的习惯)

2.如何避免

2.1.最好调用已知的String对象的equals()和equalsIgnoreCase()方法

例:a.equals(b)和b.equals(a)是完全不同的;

2.2.String.valueOf(a)和a.toString()

不知道对象是不是null时,请使用String.valueOf(a);因为null对象的toString()会抛出空指针异常

2.3.使用null安全的方法和库

有很多开源库已经做了繁重的空指针检查工作,其中最常用的是Apcahe commons 中的StringUtils。你可以使用StringUtils.isBlank(),siName(),isWhiteSpace()以及其他的工具方法

StringUtils.isEmpty(null)true
StringUtils.isBlank(null)true
StringUtils.isNumeric(null)false
StringUtils.isAllUpperCase(null)false

2.4.避免从方法中返回空指针,而是返回空collection或者空数组

这个Java最佳实践或技巧由Joshua Bloch在他的书Effective Java中提到。这是另外一个可以更好的使用Java编程的技巧。通过返回一个空collection或者空数组,你可以确保在调用如size(),length()的时候不会因为空指针异常崩溃。Collections类提供了方便的空List,Set和Map: Collections.EMPTY_LIST,Collections.EMPTY_SET,Collections.EMPTY_MAP。这里是实例:

public List getOrders(Customer customer){
    List result = Collections.EMPTY_LIST;
    return result;
}

2.5.使用annotation @NotNull 和 @Nullable

可以自定义是否为空指针,详情自行百度;技巧对程序猿来说比较新,需一段时间

2.6.避免代码中不必要的自动装包和自动解包

且不管其他如创建临时对象的缺点,如果wrapper类对象是null,自动包装同样容易导致空指针异常。例如如果person对象没有电话号码的话会返回null,如下代码会因为空指针异常崩溃。

Person ram = new Person("ram");
int phone = ram.getPhone();

当使用自动包装和自动解包的时候,不仅仅是等号,< > 同样会抛出空指针异常。可以自行百度来学习更多的Java中的自动包装和自动解包的陷阱。

2.7.遵从Contract并定义合理的默认值

在Java中避免空指针异常的一个最好的方法是简单的定义contract并遵从它们。大部分空指针异常的出现是因为使用不完整的信息创建对象或者未提供所有的依赖项。如果你不允许创建不完整的对象并优雅地拒绝这些请求,你可以在接下来的工作中预防大量的空指针异常。类似的,如果对象允许创建,你需要给他们定义一个合理的默认值。例如一个Employee对象不能在创建的时候没有id和name,但是是否有电话号码是可选的。现在如果Employee没有电话号码,你可以返回一个默认值(例如0)来代替返回null。但是必须谨慎选择,有时候检查空指针比调用无效号码要方便。同样的,通过定义什么可以是null,什么不能为null,调用者可以作出明智的决定。failing fast或接受null同样是一个你需要进行选择并贯彻的,重要的设计决策。

2.8.定义数据库中的字段是否可为空

如果你在使用数据库来保存你的域名对象,如Customers,Orders 等,你需要在数据库本身定义是否为空的约束。因为数据库会从很多代码中获取数据,数据库中有是否为空的检查可以确保你的数据健全。在数据库中维护null约束同样可以帮助你减少Java代码中的空指针检查。当从数据库中加载一个对象时你会明确,哪些字段是可以为null的,而哪些不能,这可以使你代码中不必要的!= null检查最少化。

2.9.使用空对象模式(Null Object Pattern)

还有一种方法来避免Java中的空指针异常。如果一个方法返回对象,在调用者中执行一些操作,例如Collection.iterator()方法返回迭代器,其调用者执行遍历。假设如果一个调用者并没有任何迭代器,其可以返回空对象(Null object)而非null。空对象是一个特殊的对象,其在不同的上下文中有不同的意义。例如一个空的迭代器调用hasNext()返回false时,可以是一个空对象。同样的在返回Container和Collection类型方法的例子中,空对象可以被用来代替null作为返回值。

原创文章 15 获赞 7 访问量 2676

猜你喜欢

转载自blog.csdn.net/qq_37141978/article/details/103927691