Java 不变性和一般与特定类型

Java 不变性和一般与特定类型,java,interface,guava,Java,Interface,Guava,这是在创建接口/API的上下文中进行的 最佳实践建议在接口中使用通用而不是特定类型,例如Map而不是HashMap 最佳实践还建议优先选择不可变类型而不是可变类型 因此,考虑到这两个建议(撇开对性能/内存占用、第三方库/依赖关系和便利性/功能的担忧不谈),公共接口中的方法应该是这样的吗 public List<SomeClass> someMethod(...) 公共列表方法(…) 或者更确切地说是这个 public ImmutableList<SomeClass>

这是在创建接口/API的上下文中进行的

最佳实践建议在接口中使用通用而不是特定类型,例如
Map
而不是
HashMap

最佳实践还建议优先选择不可变类型而不是可变类型

因此,考虑到这两个建议(撇开对性能/内存占用、第三方库/依赖关系和便利性/功能的担忧不谈),公共接口中的方法应该是这样的吗

public List<SomeClass> someMethod(...)
公共列表方法(…)
或者更确切地说是这个

public ImmutableList<SomeClass> someMethod(...)
公共不可变列表方法(…)

当番石榴族讨论这一问题时,有人说:

对于API交换的类型的基本建议是:选择仍然传递相关语义信息的最通用类型

我认为,在几乎任何情况下(三个是不可变的,缺少空元素和保证迭代顺序),由IMPUTABLE收集的三个语义保证与返回值极其相关。所以我实际上总是返回ImmutableSet,而不是Set

我们真的希望人们将ImmutableSet等视为每个重要意义上的接口。它们不是的原因只有两个:不变性保证的可靠性,以及Java在JDK 8之前不允许在接口上使用静态方法的事实,为了方便起见,我们需要它们

大多数人认为ImmutableList是出于这个原因的一个实现,但实际上,其中一些类型有几个到几十个不同的实现;你就是看不见他们


如果方法的契约保证列表是不可变的,那么返回类型应该是不可变列表,而不是列表。这比简单地提到列表在方法的JavaDoc中是不可变的要明确得多


但是,如果列表的不变性是一个实现细节,而不是契约,那么返回类型应该是列表

编写API就是和用户签订合同

最佳实践主要针对需要为第三方编写API并需要定义接口的环境

在不同的环境下,我们可以有不同的观点。如果您正在编写将由第三方使用的库,则需要考虑它们应该或不应该更改对象状态。 如果API将在内部使用(在相同的代码库中使用)&目的是实现松散耦合,那么您需要考虑易于编写、可扩展性和可维护性


不可变的API将避免数据不一致,特别是当您对对象的状态进行大量假设时。另一方面,可变对象将允许保存开发工作。

如果返回的列表保证是不可变的,则应将其视为2),否则应将其视为1)。什么是不可变列表?如果我不能添加到它,它真的是一个列表吗?第一个。。。但是请注意,不可变集合并不意味着其元素的不可变性;这仅仅意味着你不能更改集合本身(替换/删除/添加元素)。@JohnRasch-Oh好的,谢谢。我最近没有真正想过或遇到过这个概念。@JohnRasch你不是在和别的东西混在一起吗?番石榴的
不可变*
系列真是太棒了immutable@JohnRasch为了向调用者提供返回值的有序集合,您还希望返回什么(列表除外)?