首页 > 编程语言 >《Effective Java》第54条:返回零长度的数组或者集合,而不是null

《Effective Java》第54条:返回零长度的数组或者集合,而不是null

时间:2022-08-14 22:11:07浏览次数:49  
标签:Shop Cheese Java Effective 54 initFlag cheesesInStock return public

《Effective Java》第54条:返回零长度的数组或者集合,而不是null

一、问题

如果一个方法返回类型是list,如果结果为空的情况下返回null的情况并不少见,如下:

public class Shop_Version1 {
    private final List<Cheese> cheesesInStock = new ArrayList<>();

    public Shop_Version1(boolean initFlag) {
        if (initFlag) {
            cheesesInStock.add(Cheese.STILION);
        }
    }

    /**
     * @return a list containing all of the cheeses in the shop,
     * or null if no cheeses are available for purchase.
     */
    public List<Cheese> getCheeses() {
        return cheesesInStock.isEmpty() ? null
                : new ArrayList<>(cheesesInStock);
    }
}

这样做有一个坏处:调用这个方法的地方必须来处理null返回值,这样很容易出错。

有的认为这样做的好处是:这样做避免了分配零长度的容器所需要的开销。这种说法是站不住脚的,第一,在这个级别上是没有必要担心性能的。第二,不需要分配零长度的集合或者数组,也可以返回它们,如下:

public class Shop_Version2 {
    private final List<Cheese> cheesesInStock = new ArrayList<>();

    public Shop_Version2(boolean initFlag) {
        if (initFlag) {
            cheesesInStock.add(Cheese.STILION);
        }
    }

    /**
     * @return a list containing all of the cheeses in the shop,
     * or empty list if no cheeses are available for purchase.
     */
    public List<Cheese> getCheeses() {
        return new ArrayList<>(cheesesInStock);
    }
}

二、分析

2.1 返回集合情况优化

如果真的分配零长度的集合损害了程序的性能,可以通过重复返回一个不可变的零长度集合,避免了分配的执行,因为不可变对象可以被自由共享。如果返回的是集合,可以使用Collections.emptySet()或Collections.emptyList();如果返回的是映射,可以使用Collections.emptyMap()。这是一个优化,但是几乎用不上,如下:

public class Shop_Version3 {
    private final List<Cheese> cheesesInStock = new ArrayList<>();

    public Shop_Version3(boolean initFlag) {
        if (initFlag) {
            cheesesInStock.add(Cheese.STILION);
        }
    }

    /**
     * @return a list containing all of the cheeses in the shop,
     * or empty list if no cheeses are available for purchase.
     */
    public List<Cheese> getCheeses() {
        return cheesesInStock.isEmpty() ? Collections.emptyList()
                : new ArrayList<>(cheesesInStock);
    }
}

2.2 返回数组情况

返回数组与返回集合的情形一样,它永远不会返回null,而是返回零长度的数组。

public class Shop_RetArray_Version1 {
    private final List<Cheese> cheesesInStock = new ArrayList<>();

    public Shop_RetArray_Version1(boolean initFlag) {
        if (initFlag) {
            cheesesInStock.add(Cheese.STILION);
        }
    }

    /**
     * @return a array containing all of the cheeses in the shop,
     * or empty array if no cheeses are available for purchase.
     */
    public Cheese[] getCheeses() {
        return cheesesInStock.toArray(new Cheese[0]);
    }
}

千万不要通过预先分配传入toArray的数组来提升性能,这样只会适得其反,如下:

public class Shop_RetArray_Version2 {
    private final List<Cheese> cheesesInStock = new ArrayList<>();

    public Shop_RetArray_Version2(boolean initFlag) {
        if (initFlag) {
            cheesesInStock.add(Cheese.STILION);
        }
    }

    /**
     * @return a array containing all of the cheeses in the shop,
     * or empty array if no cheeses are available for purchase.
     */
    public Cheese[] getCheeses() {
        return cheesesInStock.toArray(new Cheese[cheesesInStock.size()]);
    }
}

2.3 返回数组情况优化

如果分配零长度的数组会伤害性能,可以重复返回同一个零长度的数组,因为所有零长度的数组都是不可变的,如下:

public class Shop_RetArray_Version3 {
    private final List<Cheese> cheesesInStock = new ArrayList<>();
    private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];

    public Shop_RetArray_Version3(boolean initFlag) {
        if (initFlag) {
            cheesesInStock.add(Cheese.STILION);
        }
    }

    /**
     * @return a array containing all of the cheeses in the shop,
     * or empty array if no cheeses are available for purchase.
     */
    public Cheese[] getCheeses() {
        return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
    }
}

三、总结

简而言之,永远不要返回null,而是返回一个零长度的数组或集合。如果返回null,那样会使API更难以使用,也列容易出错,而且没有任何性能优势。

标签:Shop,Cheese,Java,Effective,54,initFlag,cheesesInStock,return,public
From: https://www.cnblogs.com/okokabcd/p/16586523.html

相关文章

  • Java Script了解
    JavaScript了解诞生于1995年LiveScript更名为JavaScript(Netscape(网景公司)出品)JavaScript的概述JavaScript是一个轻量级的语句,他是单线程的语言(一个线程解析);他是一......
  • JavaScript关于cookie
        1.http和httpshttp,https都是网络传输协议是用于网络相关传输,http走的是明文传输,https走的密文传输(内部采用对称加密以及非对称加密)。对应的https安全性......
  • Java中Get和Post的使用
    原文链接1Get请求数据项目地址:https://github.com/Snowstorm0/learn-get-post1.1Controller文件名MyController,内容为:@RestController@RequestMapping("/homepage"......
  • 自学java第10天之接口思想
    图:1.2.3.文字解释: ......
  • JAVA基础环境 一、JDK安装与环境
    JAVA开发者所需的基础环境变量注意*以下内容请在Windows企业版或专业版配置,以免遇到不必要的麻烦一、jdk配置1.jdk下载jdk下载需要去Oracle官网下载,地址是https://www......
  • java学习第七天xml.day18
      反射在java中,反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。   获取字节码的方式:  使用反射获取构造器:    内省 ......
  • 自学java第天之obstract抽象类
    父类中,写了抽象方法:什么是抽象方法:publicobstractvoid方法(){},::::::::::::::::::;只有方法名字,没有方法实现那么如果有个类想要继承定义的这个抽象类,那么就要重写父......
  • Java企业级项目智牛股(构建金融交易一体化服务平台,打造全系列课程)
    本人java初级工程师一枚,奈何公司使用的技术比较浅层,业务面比较单一,想着提升一下自己,网上找了很多项目课程都不是很好,后来找到一个这个项目,正好满足我的需求,从整体架构的搭......
  • 自学java第7天
    面向对象011.重写仅仅针对有继承关系的父子类,且重写的是方法,不是属性;2.重写需要有继承关系才能重写,即子类重写父类的方法;3.重写的条件:这个方法是public,且不是static,因为sta......
  • Java基础的简单应用
    packagecom.zhou.partise;importjava.util.Scanner;publicclassTest01{publicstaticvoidmain(String[]args){//写一个计算器,要求实现加减乘除功能,并......