(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();
我知道,对于(1),List接口的实现可以交换。似乎(1)通常在应用程序中使用,无论是否需要(我自己总是使用它)。
我想知道是否有人使用(2)?
此外,情况实际上需要使用(1)而不是(2)的频率是多少(请给我一个例子)(即(2)是不够的..除了编码到接口和最佳实践等)。
(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();
我知道,对于(1),List接口的实现可以交换。似乎(1)通常在应用程序中使用,无论是否需要(我自己总是使用它)。
我想知道是否有人使用(2)?
此外,情况实际上需要使用(1)而不是(2)的频率是多少(请给我一个例子)(即(2)是不够的..除了编码到接口和最佳实践等)。
当前回答
(3) Collection myCollection = new ArrayList<?>();
我通常用这个。只有当我需要List方法时,我才会使用List。数组列表也是一样。你总是可以切换到更“窄”的界面,但你不能切换到更“宽”的界面。
其他回答
我认为使用(2)的人不知道利斯科夫替换原则或依赖反转原则。或者必须使用数组列表。
List几乎总是优先于ArrayList,因为,例如,List可以被转换为LinkedList而不影响其余的代码库。
如果使用ArrayList而不是List,就很难将ArrayList实现更改为LinkedList,因为代码库中已经使用了特定于ArrayList的方法,这也需要重构。
你可以在这里阅读关于List实现的信息。
您可以从ArrayList开始,但很快就会发现另一种实现是更合适的选择。
出以下两种:
(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();
第一种通常是首选。因为你将只使用List接口的方法,它为你提供了使用其他List实现的自由,例如未来的LinkedList。所以它将你与特定的实现分离。现在有两点值得一提:
我们应该始终按照接口编程。更多的在这里。 你几乎总是会使用数组列表而不是LinkedList。更多的在这里。
我想知道是否有人使用(2)
有时会(很少阅读)。当我们需要的方法是ArrayList实现的一部分而不是接口List的一部分时。例如ensureCapacity。
还有,这种情况发生的频率(以及我能得到一个例子吗) 实际上需要使用(1)而不是(2)
这是OOP中的一个经典设计模式,你总是试图将你的代码从特定的实现和程序解耦到接口。
如果code是列表的“所有者”,我使用(2)。例如,对于局部变量就是如此。没有理由使用抽象类型List而不是ArrayList。 另一个展示所有权的例子:
public class Test {
// This object is the owner of strings, so use the concrete type.
private final ArrayList<String> strings = new ArrayList<>();
// This object uses the argument but doesn't own it, so use abstract type.
public void addStrings(List<String> add) {
strings.addAll(add);
}
// Here we return the list but we do not give ownership away, so use abstract type. This also allows to create optionally an unmodifiable list.
public List<String> getStrings() {
return Collections.unmodifiableList(strings);
}
// Here we create a new list and give ownership to the caller. Use concrete type.
public ArrayList<String> getStringsCopy() {
return new ArrayList<>(strings);
}
}
列表接口有几个不同的类——ArrayList和LinkedList。LinkedList用于创建索引集合,ArrayList用于创建排序列表。你可以在你的参数中使用它,但是你可以允许其他使用你的代码,库等的开发人员使用不同类型的列表,而不仅仅是你在这个方法中使用的
ArrayList<Object> myMethod (ArrayList<Object> input) {
// body
}
你只能在ArrayList中使用它,而不是LinkedList,但是你可以允许在其他地方使用它的方法,这只是你的选择,所以使用接口可以允许它:
List<Object> myMethod (List<Object> input) {
// body
}
在这个方法参数中,你可以使用任何你想使用的List类:
List<Object> list = new ArrayList<Object> ();
list.add ("string");
myMethod (list);
结论:
尽可能在任何地方使用接口,不要限制您或其他人使用他们想要使用的不同方法。