为什么返回空集合被视为好习惯?

Cof*_*ing 7 java collections null immutability nullpointerexception

我已经阅读了几本书并看过几篇博客,讨论如何返回空集合比返回null更好.我完全理解试图避免检查,但我不明白为什么返回一个空集合比返回null更好.例如:

public class Dog{

   private List<String> bone;

   public List<String> get(){
       return bone;
   }

}
Run Code Online (Sandbox Code Playgroud)

VS

 public class Dog{

   private List<String> bone;

   public List<String> get(){
       if(bone == null){
        return Collections.emptyList();
       }
       return bone;
   }

}
Run Code Online (Sandbox Code Playgroud)

示例一将抛出NullPointerException,示例二将抛出UnsupportedOperation异常,但它们都是非常通用的异常.是什么让一个人比另一个好或坏?

另外一个选择是做这样的事情:

 public class Dog{

   private List<String> bone;

   public List<String> get(){
       if(bone == null){
        return new ArrayList<String>();
       }
       return bone;
   }

}
Run Code Online (Sandbox Code Playgroud)

但问题是,您正在为其他人可能必须维护的代码添加意外行为.

我真的在寻找解决这种困境的方法.博客上的许多人倾向于只是说没有详细解释为什么会更好.如果返回一个不可变列表是最好的做法,我可以这样做,但我想了解为什么它更好.

Mak*_*oto 7

如果您返回一个空集合(但不一定 Collections.emptyList()),则可以避免使用无意的NPE对此方法的下游消费者感到惊讶.

这比返回更可取,null因为:

  • 消费者不必防范它
  • 消费者可以对集合进行操作,而不管其中有多少元素

我不一定说Collections.emptyList(),因为你指出,你正在为另一个运营商交换一个运行时例外,因为添加到这个列表将不受支持,并再次让消费者感到惊讶.

对此最理想的解决方案: 急切初始化该字段.

private List<String> bone = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

下一个解决方案:让它返回Optional并执行某些操作以防它不存在.如果你愿意,也可以在这里提供空集合,而不是扔你.

Dog dog = new Dog();
dog.get().orElseThrow(new IllegalStateException("Dog has no bones??"));
Run Code Online (Sandbox Code Playgroud)

  • @Adam:我很乐意*在这里交换一点内存,以避免在其他地方出现一个愚蠢且完全不负责任的NPE. (2认同)

Ell*_*sch 5

因为返回空集合的替代方法通常是返回null; 然后调用者必须添加防护措施NullPointerException。如果您返回一个空集合,则可以减轻该类错误。在 Java 8+ 中还有一种Optional类型,无需Collection.

  • 谁说空集合**必须**是*不可变的*列表?如果您计划向其中添加项目,请不要返回*不可变*列表。 (2认同)