Should I declare/Initialize ArrayLists as Lists, ArrayLists, or ArrayLists of <Cat>
What is the difference in declaring a collection as such
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>();
}
}
You should declare it as a List<Cat>
, and initialize it as an ArrayList<Cat>
.
List
is an interface, and ArrayList
is an implementing class. It's almost always preferable to code against the interface and not the implementation. This way, if you need to change the implementation later, it won't break consumers who code against the interface.
Depending on how you actually use the list, you might even be able to use the less-specific java.util.Collection
(an interface which List
extends).
As for List<Cat>
(you can read that as "list of cat") vs List
: that's Java's generics, which ensure compile-time type safely. In short, it lets the compiler make sure that the List
only contains Cat
objects.
public class CatHerder{
private final List<Cat> cats;
public CatHerder(){
this.cats = new ArrayList<Cat>();
}
}
I would do the following.
public class CatHerder{
private final List<Cat> cats = new ArrayList<Cat>();
}
In order to ensure type safety, and because current Java compilers will complain if a generic type has no type argument, you should always specify a type explicitly - or <?>
if you really don't care.
That said, unless you use something specific to the ArrayList
class, you should use List<Cat>
to avoid tying your code to a particular List
implementation.
As Matt already stated, using the most common Interface/Superclass is the best way to go here.
Make sure to always declare the Type that appears in your List, so make it a List<Cat>
or even List<? extends Cat>
If, at some later point, you want to replace the ArrayList
with, say, a LinkedList
, you won't have to change the declaration, but only the instantiation.
List
is more flexible than ArrayList
, List<Cat>
is safer than List
. so List<Cat>
is good choice.
First of all, List
is an interface and ArrayList
is an implementation of the List
interface (actually, it subclasses AbstractList
and implements List
). Therefore List cats = new ArrayList()
is valid since ArrayList
is-a List
.
For this:
private List cats;
cats
becomes a raw-type (there is no reference to the Generic Type for List
), it hasn't been parameterised.
Your 3rd solution is correct (it solves your problem for option 1),
private ArrayList<Cat> cats;
you have bounded a Generic Type E
for List<E>
to a type Cat
. Therefore, your instantiation of cats
is valid as the generic bounding is the same.
Your 2nd solution allows that only ArrayList
of cats
can be instantiated. The other 2 options allows you to instantiate any object that is-a List
, e.g. LinkedList
.
精彩评论