返回零长度的数组或集合,而不是null

像下面的方法并不少见:

private final List<Cheese> cheesesInStock = ...;
/**
* @return an array containing all of the cheeses in the shop,
* or null if no cheese are available for purchase.
*/
public Cheese[] getCheeses(){
if(cheesesInStock.size() == 0)
return null;
...
}

把没有奶酪(cheese)可买的情况当做一种特例,这是不合理的。这样做会要求客户端必须有额外的代码来处理null返回值,例如:

Cheese[] cheeses = shop.getCheeses();
if(chesses != null && Arrays.asList(cheeses).contains(Chees.STILTON))
System.out.println("Joll good, just the thing.");

而不是下面这些代码:

if(Arrays.asList(cheeses).contains(Chees.STILTON))
System.out.println("Joll good, just the thing.");

对于一个返回null而不是令狐冲那个度数组或者集合的方法,几乎每次都要用到该方法时都需要这种曲折的处理方式。这样做很容易出错,因为编写客户端程序的程序员可能会忘记这种专门的代码处理null的返回值。这样的错误也许几年都不会注意到,因为这样的方法通常返回一个或者多个对象。返回null而不是零长度的数组也会返回数组或者集合的方法本身变得更加复杂,这一点虽然不是特别重要,但是也值得注意。

有时候会有人认为:null返回值比零长度数组更好,因为它避免了分配数组所需要的开销。这种观点是站不住脚的,原因有两点。第一这个级别上担心性能问题是不明智的,除非分析表明这个方法正是造成性能问题的真正源头。第二,对于不返回任何元素的调用,每次都返回同一个零长度数组有可能的,因为零长度数组是不可变的,而不可变的对象有可能被自由的共享。实际上,当你使用标准化做法把一些元素从一个集合转存到一个类型化的数组中时,它正是这样做的:

// The rigth way to return an aray from a collection
private final List<Cheese> cheesesInStock = ...;
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
/**
* @return an array containing all of the cheeses in the shop,
* or null if no cheese are available for purchase.
*/
public Cheese[] getCheeses(){
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}

在这种习惯用法中,零长度数组常量被传递给toArray方法,以指明所期望的返回类型。toArray方法分配了返回的数组,但是,如果集合是空,它将使用零长度的出入数组,Collection.toArray(T[])的规范保证:如果输入的数组大到足够容纳这个集合,它将返回这个输入数组。因此,这种做法永远也不会分配到零长度的数组。

同样的,集合值的方法也可以做成在每当需要返回同一个不可变的空集合。Collections.emptySet、emptyList和emptyMap方法提供的正是你需要的。

// The right way to return a cope of a collection
public List<Cheese> getCheeseList(){
if(cheeseInStock.isEmpt())
return Collections.emptyList();//Always return same list
else
return new ArrayList<Cheese>(cheesesInStock);
}

简而言之,返回类型为数组或者几何的方法没有理由返回null,而是返回一个零长度的数组或者集合。

返回零长度的数组或集合,而不是null的更多相关文章

  1. Effective Java 之-----返回零长度的数组或集合而不是null

    如下代码,通常用户列表为空时,会习惯性返回null,因为这时会认为:null返回值比零长度数组更好,因为它避免了分配数组所需要的开销. private final List<UserBean&g ...

  2. Effective java 43返回零长度的数组或者集合而不是null

  3. 返回零长度的数组或者集合,而不是null

    <<Effective Java>> 第四十三条:返回零长度的数组或者集合,而不是null 假设一个方法的返回值类型是集合或者数组 .假设在方法内部须要返回的集合或者数组是零长 ...

  4. 第四十三条:返回零长度的数组或者集合,而不是null

    如果一个方法的返回值类型是集合或者数组 ,如果在方法内部需要返回的集合或者数组是零长度的,也就是没有实际对象在里面, 我们也应该放回一个零长度的数组或者集合,而不是返回null.如果返回了null,客 ...

  5. 第43条:返回零长度的数组或者集合,而不是null

    private final List<Cheese> cheesesInStock = ...; public Cheese[] getCheese() { if(cheesesInSto ...

  6. GNU C 中零长度的数组【转】

    原文链接:http://www.cnblogs.com/dolphin0520/p/3752492.html 在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNU C中,存在一个非常奇怪的用 ...

  7. 读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

    原文链接:C语言结构体里的成员数组和指针 复制例如以下: 单看这文章的标题,你可能会认为好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Lar ...

  8. C语言 结构体中的零长度数组

    /* C语言零长度数组大小和取值问题 */ #include <stdio.h> #include <stdlib.h> #include <string.h> s ...

  9. 【Java】返回长度为零的数组或者集合,而不是null

    今天在牛客网上做一个编程题时,在提交代码后老是抛出NullPointerException异常,大概的代码如下: public ArrayList<Integer> foo(TreeNod ...

随机推荐

  1. linux修改进程的名字

    1 修改linux进程名字的基本原理 linux进程以argv[0]作为进程的名字,因此只需要修改argv[0]处的字符串就修改了linux进程的名字. 2 直接修改argv[0]会导致的问题 如果名 ...

  2. android开发基础知识了解

    JDK下载:www.oracle.com; SDK下载:www.android.developer.com; eclipse下载:www.eclipse.org;

  3. git基本操作---持续更新(2017-08-11)

    git 强制push $ git push -u origin master -f 查看本地标签 $ git tag 打标签并添加备注 $ git tag 20170811 -m"图片保存多 ...

  4. 初学php html javascript后小总结

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/c3568/article/details/30474015 转载请注明出处:http://blog. ...

  5. 设置VIM查找时不区分大小写

    :set ic 永久生效 vi ~/.vimrc set ic

  6. Raspberry Pi3 ~ C语言控制串口

    注明出处:http://www.cnblogs.com/einstein-2014731/p/5551846.html 使用C语言控制树莓派3B的串口,实现使用串口收发数据的目的.之前以为这个串口是被 ...

  7. Struts action

    <action name="KnowledgeBankManageAction_*" class="knowledgeBankManageAction" ...

  8. Docker的跨主机连接:

    1使用网桥实现跨主机容器连接. 2使用open vswitch虚礼的交换机实现跨主机容器连接. 3使用weave开源项目工具实现跨主机连接. 使用网桥实现跨主机容器连接:在同一个docker的主机中d ...

  9. javascrip中ajax

    移动端对加载速度要求比较高,由于jquery插件有270多k,无形中增加加载的速度,下面整理一下原生js中ajax: 先了解ajax的基础知识 (1)XMLHttpRequest 对象 XMLHttp ...

  10. golang 关于golang.org/x包问题

    关于golang.org/x包问题 由于谷歌被墙,跟谷歌相关的模块无法通过go get来下载,解决方法: git clone https://github.com/golang/net.git $GO ...