使用guava immutable集合作为方法参数和/或返回类型

use*_*479 15 java immutability guava

我试图确定ImmutableList的最佳实践.以下是一个简单的例子,有助于解决我的问题:

例如:

public ImmutableCollection<Foo> getFooOne(ImmutableList<Foo> fooInput){ 
   //.. do some work
   ImmutableList<Foo> fooOther = // something generated during the code
   return fooOther;
}

public Collection<Foo> getFooTwo(List<Foo> fooInput){
   //.. do some work
   List<Foo> fooOther = // something generated during the code
   return ImmutableList.copyOf(fooOther);
}

public void doSomethingOne(){
  ImmutableCollection<Foo> myFoo = getFooOne(myList);
  ...
  someOtherMethod(myFoo);
}

public void doSomethingTwo(){
  Collection<Foo> myFoo = getFooOne(myList);
  ...
  someOtherMethod(myFoo);
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 哪个在应用程序中最有意义?[doSomethingOne和getFooOne]或[doSomethingTwo和fooTwo]?换句话说,如果你知道你正在使用ImmutableCollections,那么继续来回和执行copyOf(),或者只是在各地使用Immutable是有意义的吗?

  2. 这些示例是公共方法,可能意味着其他人使用它们.如果这些方法是私有的并且在内部使用,那么这些答案会改变吗?

  3. 如果用户尝试向不可变List添加任何内容,则将抛出异常.因为他们可能没有意识到这一点,显然返回一个ImmutableCollection而不是Collection会更有意义吗?

Chr*_*irk 18

通常,明智的做法是不在已声明的返回类型中提交特定实现,但我们将不可变类型视为异常.声明返回类型有几个原因Immutable*:

  • 他们记录您正在返回快照,而不是实时视图.
  • 他们记录了调用者不能改变结果.
  • 他们记录了保留了插入顺序(在您的用例中可能会或可能不会很重要).
  • 他们记录了该集合不包含的内容null.
  • 有人可能想要asList()reverse()方法.
  • copyOf()如果他希望分配给某个Immutable*字段,您可以保存某个人.(但请注意,如果他确实包含copyOf(),它将为大多数不可变输入短路,即使您没有声明返回类型.)

基本上,我只是来自https://github.com/google/guava/wiki/TenThingsAboutImmutableCollections,您可能想要完整地查看.