为什么 Guava 不可变集合接口?



Guava的ImmutableCollection有像ImmutableList这样的子类,它们是(不可扩展的)抽象类而不是接口。文档说这是为了防止外部子类型。另一方面,文档还说他们

应该被认为是每个重要意义上的接口

但是,外部子类型的能力难道不是界面的重要意义吗?例如,如果ImmutableList是一个接口,我可以有一个方法签名,例如

public ImmutableList<String> getNames();

(如 Guava 建议),然后可以灵活地在将来交换ImmutableList的自定义实现。但是,由于实际上它是一个抽象类,我没有这种灵活性,因此受Guava的实现的约束。因此,如果我想保持这种灵活性,我将不得不恢复使用更通用的返回类型List,它不再向调用者传达有关不变性的有用信息:

public List<String> getNames();

那么,为什么这些不是外部子类型很重要呢?一个答案可能是,Guava设计人员不信任外部实现者正确支持所需的语义,但List本身实际上具有相当广泛的契约,并且没有人阻止其自定义实现。还是有其他原因?

这是因为如果它是一个接口,则无法拥有保证不可变性的类型ImmutableList

不,我不认为任何人编写自己的interface实现的能力是所有接口的必要属性。例如,考虑密封类型,它们只允许在同一文件中定义的一组特定实现。它们仍然可以interface(这里有一个提案包括 Java 的sealed interface),而不允许世界上的任何人创建它们的实现。

我也真的很好奇,为什么你会认为你可能想要自己的自定义实现一些超级简单的东西,比如不可变列表。

最新更新