5
Collection list = new LinkedList(); // Good?
LinkedList list = new LinkedList(); // Bad?

第一个变体提供了更大的灵活性,但仅此而已吗?还有其他喜欢它的理由吗?性能呢?

4

6 回答 6

7

这些是设计决策,一种尺寸通常并不适合所有人。此外,成员变量内部使用的内容的选择可以(并且通常应该)不同于暴露给外部世界的内容。

从本质上讲,Java 的集合框架并没有提供一套完整的接口来描述性能特征而不暴露实现细节。描述性能的一个接口RandomAccess是标记接口,甚至不扩展Collection或重新公开get(index)API。所以我认为没有一个好的答案。

根据经验,在我识别(并记录)一些重要的特征之前,我会尽可能保持类型不具体。例如,一旦我想让方法知道保留插入顺序,我就会从Collectionto更改为List,并记录为什么该限制很重要。同样,如果说从前面有效移除变得很重要,那么从List到移动。LinkedList

在公开 API 中公开集合时,我总是尝试只公开少数预期会被使用的 API;例如add(...)iterator()

于 2013-03-19T21:00:56.110 回答
2
Collection list = new LinkedList(); //bad

这很糟糕,因为您不希望这个引用引用一个 HashSet(因为 HashSet 也实现了 Collection,集合框架中的许多其他类也是如此)。

LinkedList list = new LinkedList(); //bad?

这很糟糕,因为好的做法是始终对接口进行编码。

List list = new LinkedList();//good

这很好,因为点 2 天。(总是编程到接口

于 2013-03-19T20:49:04.273 回答
2

对非公共对象使用最具体的类型信息。它们是实现细节,我们希望我们的实现细节尽可能具体和精确。

于 2013-03-19T20:52:10.853 回答
1

当然。例如,如果 java 会为 List 集合找到并实现更有效的实现,但您已经拥有只接受 LinkedList 的 API,如果您已经有此 API 的客户端,您将无法替换实现。如果您使用接口,您可以轻松地替换实现而不破坏 API。

于 2013-03-19T20:50:15.970 回答
0

它们是绝对等价的。使用其中一个的唯一原因是,如果您以后要使用仅存在于类 LinkedList 中的列表功能,则需要使用第二个。

于 2013-03-19T20:48:52.003 回答
0

我的一般规则是只在你当时需要的具体情况下(或在不久的将来,在合理范围内)。当然,这有点主观。

在您的示例中,我通常将其声明为 aList只是因为可用的方法不是很强大,并且 a和另一个(,等)Collection之间的区别通常在逻辑上很重要。ListCollectionMapSet

此外,在 Java 1.5+ 中不要使用原始类型——如果您不知道列表将包含的类型,至少使用List<?>.

于 2013-03-19T20:59:58.800 回答