这就是所谓的接口编程。如果您希望今后转向其他执行清单的方式,这将有所帮助。如果您想在 ArrayList中使用一些方法,那么您需要编程实现为 ArrayList a = new ArrayList()

这使您能够编写如下内容:

void doSomething() {
List<String>list = new ArrayList<String>();
//do something
}

稍后,你可能会想把它改成:

void doSomething() {
List<String>list = new LinkedList<String>();
//do something
}

而不必改变方法的其余部分。

但是,如果您想使用一个 CopyOnWriteArrayList,例如,您需要将它声明为这样的,而不是列表 如果你想使用它的额外方法(例如 addIfAbsent) :

void doSomething() {
CopyOnWriteArrayList<String>list = new CopyOnWriteArrayList<String>();
//do something, for example:
list.addIfAbsent("abc");
}

只要我不想增加问题的复杂性,我就会使用这种结构。它只是一个列表,不需要说它是什么类型的列表,因为它与问题无关。我经常在大多数解决方案中使用 Collection,因为最后,大多数情况下,对于软件的其余部分,真正重要的是它保存的内容,我不想向 Collection 添加新对象。

此外,当您认为可能需要更改正在使用的 list 的实现时,可以使用该构造。假设您使用的是数组列表的构造,并且您的问题不是线程安全的。现在,您希望使它成为线程安全的,并且对于您的解决方案的一部分,您更改为使用 Vector,例如。至于该列表的其他用途,不管它是 AraryList 还是 Vector,只要是 List 就行,不需要做任何新的修改。

这样做的主要原因是为了将代码与接口的特定实现解耦。当你这样写代码的时候:

List list = new ArrayList();

代码的其余部分只知道数据是 List类型的,这更好,因为它允许您轻松地在 List接口的不同实现之间切换。

例如,假设您正在编写一个相当大的第三方库,并假设您决定使用 LinkedList实现库的核心。如果您的库严重依赖于访问这些列表中的元素,那么最终您会发现您做出了一个糟糕的设计决策; 您将意识到您应该使用 ArrayList(给予 O (1)访问时间)而不是 LinkedList(给予 O (n)访问时间)。假设您已经编写了一个接口,那么进行这样的更改是很容易的。您只需将 List的实例从,

List list = new LinkedList();

List list = new ArrayList();

并且您知道这将工作,因为您已经编写了遵循 List接口提供的契约的代码。

另一方面,如果您已经使用 LinkedList list = new LinkedList()实现了库的核心,那么进行这样的更改将不会那么容易,因为不能保证您的其余代码不会使用特定于 LinkedList类的方法。

总而言之,选择只是一个设计问题... ... 但是这种设计非常重要(特别是在大型项目中) ,因为它允许您以后在不破坏现有代码的情况下进行特定于实现的更改。

一般来说,您需要根据接口进行编程,这允许您在任何时候交换实现。 这是非常有用的,特别是当您得到一个您不知道的实现时。

但是,在某些情况下,您更愿意使用具体的实现。 例如,在 GWT 中序列化时。

这在公开公共接口时也很有用,

public ArrayList getList();

然后你决定改成,

public LinkedList getList();

任何正在做 ArrayList list = yourClass.getList()的人都需要改变他们的代码。另一方面,如果你这样做,

public List getList();

对于 API 的用户来说,更改实现并不会改变任何东西。

我想你的问题的核心是为什么到 program to an interface, not to an implementation

仅仅是因为接口提供了更多的抽象,并使代码 更加灵活和适应变化,因为您可以使用不同的 实现相同的接口(在本例中,您可能希望将 List 实现更改为 linkedList 而不是 ArrayList)而不更改其客户端。

我认为@tsatiz 的回答大部分是正确的(编程到一个接口而不是一个实现)。

如果将变量声明为 List<type> list = new ArrayList<type> ,实际上并不会丢失 ArrayList 的 任何功能。你所需要做的就是把你的 list转换成 ArrayList。这里有一个例子:

List<String> list = new ArrayList<String>();
((ArrayList<String>) list).ensureCapacity(19);

最终,我认为 tsatiz 是正确的,因为一旦你强制转换到数组列表,你就不再需要编写接口代码了。但是,最初编写接口代码仍然是一种很好的做法,如果以后有必要,还可以编写实现代码。

希望能帮上忙!