(1) List<?> myList = new ArrayList<?>();

(2) ArrayList<?> myList = new ArrayList<?>();

我知道,对于(1),List接口的实现可以交换。似乎(1)通常在应用程序中使用,无论是否需要(我自己总是使用它)。

我想知道是否有人使用(2)?

此外,情况实际上需要使用(1)而不是(2)的频率是多少(请给我一个例子)(即(2)是不够的..除了编码到接口和最佳实践等)。


当前回答

例如,你可能认为LinkedList是应用程序的最佳选择,但后来又认为ArrayList可能是更好的选择。

Use:

List list = new ArrayList(100); // will be better also to set the initial capacity of a collection 

而不是:

ArrayList list = new ArrayList();

供参考:

(主要用于收集图)

其他回答

出以下两种:

(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();

第一种通常是首选。因为你将只使用List接口的方法,它为你提供了使用其他List实现的自由,例如未来的LinkedList。所以它将你与特定的实现分离。现在有两点值得一提:

我们应该始终按照接口编程。更多的在这里。 你几乎总是会使用数组列表而不是LinkedList。更多的在这里。

我想知道是否有人使用(2)

有时会(很少阅读)。当我们需要的方法是ArrayList实现的一部分而不是接口List的一部分时。例如ensureCapacity。

还有,这种情况发生的频率(以及我能得到一个例子吗) 实际上需要使用(1)而不是(2)

这是OOP中的一个经典设计模式,你总是试图将你的代码从特定的实现和程序解耦到接口。

事实上,有些情况下(2)不仅是首选的,而且是强制性的,我很惊讶,这里没有人提到这一点。

串行化!

如果您有一个可序列化的类,并且希望它包含一个列表,那么您必须将字段声明为具体的可序列化类型,例如ArrayList,因为list接口没有扩展java.io.Serializable

显然,大多数人不需要序列化,忘记了这一点。

一个例子:

public class ExampleData implements java.io.Serializable {

// The following also guarantees that strings is always an ArrayList.
private final ArrayList<String> strings = new ArrayList<>();

List是一个接口。它没有方法。当你调用List引用上的方法时,它实际上在这两种情况下都调用了ArrayList的方法。

将来你可以将List obj = new ArrayList<>更改为List obj = new LinkList<>或其他实现List接口的类型。

我会说1是首选,除非

你依赖于ArrayList中可选行为*的实现,在这种情况下显式使用ArrayList更清楚 你将在一个需要ArrayList的方法调用中使用ArrayList,可能用于可选的行为或性能特征

我的猜测是,在99%的情况下,您可以使用List,这是首选。

为实例removeAll,或add(null)

(3) Collection myCollection = new ArrayList<?>();

我通常用这个。只有当我需要List方法时,我才会使用List。数组列表也是一样。你总是可以切换到更“窄”的界面,但你不能切换到更“宽”的界面。