• 关于“Return empty arrays or collections, not nulls”的思考


    《effective java》第二版第43条是:Return empty arrays or collections, not nulls

    意思是在需要返回数组或者集合的方法中,如果需要返回空数据,不要返回null,而是要返回大小为0的数组或者集合。

    可能很多情况下,会出现这样的代码:

     1 private final List<Cheese> cheesesInStock = ...;
    2 /**
    3 * @return an array containing all of the cheeses in the shop,
    4 * or null if no cheeses are available for purchase.
    5 */
    6 public Cheese[] getCheeses() {
    7   if (cheesesInStock.size() == 0)
    8     return null;
    9   ...
    10 }

    当没有数据时,直接返回null。

    但是,采用此种方式,会出现一个问题,就是调用这个代码的client必须要判断这个方法返回的是否为null,否则,可能会抛出NullPointerException异常。

    比如:

    代码1:

    1 Cheese[] cheeses = shop.getCheeses();
    2 if (cheeses != null &&
    3 Arrays.asList(cheeses).contains(Cheese.STILTON))
    4   System.out.println("Jolly good, just the thing.");

    每一次调用都要加上是否为null的判断,而且很容易忘记检查导致抛出异常。

    有人坚持选择返回null的原因是因为,他们认为分配一个空数组或者集合是需要花费时间和空间的,会影响性能。而作者则认为:

    1)这点性能损耗微不足道;

    2)返回的空数组或者集合通常是immutable,即不可变的。所以可定义成static final(对于数组)或者Collections.emptyList()/emptyMap()/emptySet()来公用同一个对象,减少性能影响。

    代码2:

    1 // The right way to return an array from a collection
    2 private final List<Cheese> cheesesInStock = ...;
    3 private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
    4 /**
    5 * @return an array containing all of the cheeses in the shop.
    6 */
    7 public Cheese[] getCheeses() {
    8   return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
    9 }
    
    

    代码3:

    1 // The right way to return a copy of a collection
    2 public List<Cheese> getCheeseList() {
    3   if (cheesesInStock.isEmpty())
    4     return Collections.emptyList(); // Always returns same list
    5   else
    6     return new ArrayList<Cheese>(cheesesInStock);
    7 }

    几点思考:

    1)自己写接口方法时尽量遵守这条规范,并在方法注释中标明。返回大小为0的数组或者集合。

    2)文中提到的Collections.emptyList()/emptyMap()/emptySet()这个需要慎用。因为这几个方法返回的集合对象都是immutable的,即不可更改的。而有时候我们可能需要向返回的集合中添加或者删除元素,这样的话,就会报UnsupportedOperationException异常。

    3)tips:

      a) 当要判断某个元素是否在数组中时,可以Arrays.asList(T[] array).contains(T obj))来实现,而无需用循环迭代每个元素来判断。

      b) 如代码2所示,如果要把ArrayList变成数组,可以使用ArrayList.toArray(T [] array),里面的array只需设成大小为0的数组即可,仅用来指定返回的类型,T可能为ArrayList中元素的子类。




  • 相关阅读:
    java学习笔记07-循环
    java学习笔记06-条件语句
    java学习笔记05-运算符
    java学习笔记04-基本数据类型
    java学习笔记03-基本语法
    java学习笔记02-Eclipse IDE配置
    java学习笔记01-环境配置
    Jmeter学习笔记03-元件作用域及执行顺序
    JMeter学习笔记02-基础介绍
    [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)
  • 原文地址:https://www.cnblogs.com/gaojing/p/2424014.html
Copyright © 2020-2023  润新知