开发者

Should I declare/Initialize ArrayLists as Lists, ArrayLists, or ArrayLists of <Cat>

开发者 https://www.devze.com 2023-02-20 15:25 出处:网络
What is the difference in declaring a collection as such public class CatHerder{ private List cats; public CatHerder(){

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消