声明集合本身有什么不同
public class CatHerder{
private List cats;
public CatHerder(){
this.cats = new ArrayList<Cat>();
}
}
//or
public class CatHerder{
private ArrayList cats;
public CatHerder(){
this.cats = new ArrayList();
}
}
//or
public class CatHerder{
private ArrayList<Cat> cats;
public CatHerder(){
this.cats = new ArrayList<Cat>();
}
}
答案 0 :(得分:22)
您应将其声明为List<Cat>
,并将其初始化为ArrayList<Cat>
。
List
是一个接口,ArrayList
是一个实现类。对接口而不是实现进行编码几乎总是更可取。这样,如果您以后需要更改实现,它将不会破坏针对该接口编码的消费者。
根据您实际使用列表的方式,您甚至可以使用不太具体的java.util.Collection
(List
扩展的接口)。
至于List<Cat>
(您可以将其视为“猫的列表”)与List
:这是Java的generics,它可以安全地确保编译时类型。简而言之,它允许编译器确保List
仅包含Cat
个对象。
public class CatHerder{
private final List<Cat> cats;
public CatHerder(){
this.cats = new ArrayList<Cat>();
}
}
答案 1 :(得分:4)
我会做以下事情。
public class CatHerder{
private final List<Cat> cats = new ArrayList<Cat>();
}
答案 2 :(得分:1)
为了确保类型安全,并且因为当前的Java编译器会抱怨泛型类型没有类型参数,所以应该始终明确指定类型 - 或<?>
如果你真的不在乎。
尽管如此,除非您使用ArrayList
类的特定内容,否则应使用List<Cat>
来避免将代码绑定到特定的List
实现。
答案 3 :(得分:1)
Matt已经说过,使用最常见的Interface / Superclass是最好的方式。
请务必始终声明列表中显示的类型,因此请将其设为List<Cat>
甚至List<? extends Cat>
如果稍后要将ArrayList
替换为LinkedList
,则不必更改声明,只需更改实例化。
答案 4 :(得分:1)
List
比ArrayList
更灵活,List<Cat>
比List
更安全。所以List<Cat>
是不错的选择。
答案 5 :(得分:1)
首先,List
是一个接口,ArrayList
是List
接口的实现(实际上,它是子类AbstractList
和implements List
)。因此,List cats = new ArrayList()
有效,因为ArrayList
是 List
。
为此:
private List cats;
cats
成为原始类型(没有List
的通用类型的引用),它尚未参数化。
您的第3个解决方案是正确的(它解决了选项1的问题),
private ArrayList<Cat> cats;
您已将E
的通用类型List<E>
限定为类型Cat
。因此,cats
的实例化是有效的,因为通用边界是相同的。
您的第二个解决方案允许只ArrayList
个cats
实例化。其他2个选项允许您实例化是 List
的任何对象,例如LinkedList
。