(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)是不够的..除了编码到接口和最佳实践等)。
当前回答
如果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);
}
}
其他回答
(3) Collection myCollection = new ArrayList<?>();
我通常用这个。只有当我需要List方法时,我才会使用List。数组列表也是一样。你总是可以切换到更“窄”的界面,但你不能切换到更“宽”的界面。
如果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);
}
}
事实上,有些情况下(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接口的类型。
例如,你可能认为LinkedList是应用程序的最佳选择,但后来又认为ArrayList可能是更好的选择。
Use:
List list = new ArrayList(100); // will be better also to set the initial capacity of a collection
而不是:
ArrayList list = new ArrayList();
供参考:
(主要用于收集图)