为什么枚举被转换为ArrayList而不是java.utils中的List?

2022-08-31 13:31:19

包中的 Collections.list() 方法返回一个而不是 ?java.utilsArrayList<T>List<T>

显然,an 是一个 ,但我的印象是,通常最好返回接口类型而不是实现类型。ArrayListList


答案 1

免责声明:我不是JDK作者。

我同意将自己的代码写入接口是正确的,但是如果您要将可变集合返回给第三方,那么让第三方知道他们要返回的是哪种类型是很重要的。List

LinkedList并且对于各种操作,性能方面非常不同。例如,删除 的第一个元素是 ,但删除 的第一个元素是 。ArrayListArrayListO(n)LinkedListO(1)

通过完全指定返回类型,JDK 作者可以在明确的代码中传达有关他们返回给您的对象类型的额外信息,因此您可以编写代码以正确使用此方法。如果你真的需要一个 ,你知道你必须在这里指定一个。LinkedList

最后,通过实现对接口进行编码的主要原因是,如果您认为实现会发生变化。JDK的作者可能认为他们永远不会改变这种方法。它永远不会返回 a 或 a .但是,在大多数情况下,您可能仍然会这样做:LinkedListCollections.UnmodifiableList

List<T> list = Collections.list(enumeration);

答案 2

返回时,您将程序提升到界面,这是一个非常好的做法。但是,这种方法有其局限性。例如,不能使用为接口定义且不存在的某些方法 - 有关详细信息,请参阅此答案ListArrayListList

我引用了 Java™ 教程中的 API 设计

...可以返回实现扩展其中一个集合接口的任何类型的对象。这可以是其中一个接口,也可以是扩展或实现这些接口之一的特殊用途类型。

..从某种意义上说,返回值应具有与输入参数相反的行为:最好返回最具体的适用集合接口,而不是最通用的集合接口。例如,如果您确定始终返回 a,则应为相关方法指定返回类型,而不是 。 实例的构建比普通实例更耗时,而且功能更强大。鉴于您的模块已经投入了时间来构建 ,因此让用户访问其增加的功能是很有意义的。此外,用户将能够将返回的对象传递给需要 a 的方法以及接受任何 .SortedMapSortedMapMapSortedMapMapSortedMapSortedMapMap

由于本质上是一个数组,因此当我需要拥有“集合数组”时,它们是我的首选。因此,如果我想将枚举转换为列表,我的选择将是数组列表。ArrayList

在任何其他情况下,编写以下内容仍然有效:

List<T> list = Collections.list(e);