程序员你是如何降低NPE的?

image.png

程序员,如果系统突然报了一个空指针异常,你肯定像吞了一只苍蝇一样尴尬。

那么如何在日常开发过程中降低NPE?

问题 回答
现状 返回空值会出现大量的空指针异常
目的 改进方法的返回值,降低出现空指针异常
实现路径 方法返回空集合或者空数组

跟我来!

背景

下面的方法看起来很常见。

private final List<Chesse> chessesInStock= ...

public List<Cheese> getCheeses(){
	return cheesesInStock.isEmpty()?null:new ArrayList<>(cheesesInStock);
}

假如你去购买芝士的时候没有可用的芝士,似乎没有理由特别指出这种场景。

但是你这么做的话,客户端需要添加额外代码来处理可能返回空值的情况。示例代码如下:

List<Cheese> cheeses = shop.getCheeses();

if(cheses != null && cheeses.contains(Cheese.STILTON)){
	System.out.println("jolly good");
}

每一个返回空值的方法都使用上面这种处理方式,应该替换为返回一个空集合或者空数组。

这是一种错误的趋势,因为程序员些客户端代码可能会忘记写特殊代码来处理返回的空值。

这个错误可能会持续很长时间,因为这样的方法通常会返回一个或多个对象。

不返回空集合空数组的争论

返回空值替换为返回空容器也会使得方法的实现变得复杂。

通常争论的是:返回空值比返回空集合更好是因为创建一个空的容器有性能消耗。

这个论点不对,原因有两点:

一,没有必要担心性能除非有证据显示创建一个空容器整的有损性能;

二,你可以返回一个空集合或者数组而不用创建它们。

返回空集合

下面是一个典型的代码返回一个可能的空集合,通常,这就是你所需要的。

public List<Cheese> getCheeses(){
	return new ArrayList<>(cheeseInStock);
}

没有证据证明创建一个空集合会有损性能,你可以返回一个相同的不可变空集合来避免创建空集合。因为不可变对象是可以被自由共享的,下面是使用代码。

需求场景 代码
空List Collections.emptyList()
空Set Collections.emptySet()
空Map Collections.emptyMap()

但是记住,以上这些操作是只是优化,很少被调用,如果你认为你需要它,在调用前后进行性能对比,确保它真的有用。

public List<Cheese> getCheeses(){
	return cheesesInStock.isEmpty()?Collections.emptyList():new ArrayList<>(cheesesInStock);
}

返回空数组

使用数组的场景跟集合是相同的,永远不要返回空值,应该返回一个长度位0的数组,常常,你应该简单的返回一个有适当长度的数组,也许长度是0。

注意我们传递一个长度为0的数组到toArray方法中来代表期望的返回类型;

public Cheese[] getCheeses(){
	return cheesesInStock.toArray(new Cheese[0]);
}

如果你认为创建一个长度为0的数组会降低性能,你可以返回同一个长度为0的数组,因为所有长度为0的数组都是不可变的;

private static final Cheese[] EMPTY_ARRAY= new Cheese[0];

public Cheeses[] getCheeses(){
	return cheesesInStock.toArray(EMPTY_ARRAY);
}

在优化版本中,我们传递了同一个空的数组到每一个toArray的调用,这个数组将会从getCheeses返回,无论cheesesInStock是不是空的,不要期望预分配数组可以提高性能,研究显示这是适得其反的。

return cheesesInStock.toArray(new Cheese[cheesesInStock.size()]);

小结

如果你只能记住一句话:返回空集合或者数组而不要返回空值

返回空值会让你的API更难使用并且更容易出错,并且无性能优势;

image.png

原创不易,关注诚可贵,转发价更高!转载请注明出处,让我们互通有无,共同进步,欢迎沟通交流。

优秀的个人博客,低调大师

微信关注我们

原文链接:https://my.oschina.net/carterspring/blog/4571473

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Eclipse(集成开发环境)

Eclipse(集成开发环境)

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。