Должен ли я объявлять/инициализировать ArrayLists как списки, ArrayLists или ArrayLists <Cat>
В чем разница в объявлении коллекции как таковой
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>();
}
}
Ответы
Ответ 1
Вы должны объявить его как List<Cat>
и инициализировать его как ArrayList<Cat>
.
List
- это интерфейс, а ArrayList
- это класс реализации. Это почти всегда предпочтительнее кода против интерфейса, а не реализации. Таким образом, если вам нужно будет изменить реализацию позже, это не приведет к поломке потребителей, которые кодируют интерфейс.
В зависимости от того, как вы на самом деле используете этот список, вы даже можете использовать менее конкретный java.util.Collection
(интерфейс, который List
расширяет).
Что касается List<Cat>
(вы можете прочитать это как "список кошек" ) vs List
: что Java generics, которые обеспечивают время компиляции типа безопасно. Короче говоря, он позволяет компилятору убедиться, что List
содержит только объекты Cat
.
public class CatHerder{
private final List<Cat> cats;
public CatHerder(){
this.cats = new ArrayList<Cat>();
}
}
Ответ 2
Я бы сделал следующее.
public class CatHerder{
private final List<Cat> cats = new ArrayList<Cat>();
}
Ответ 3
Чтобы обеспечить безопасность типов, и поскольку текущие компиляторы Java будут жаловаться, если общий тип не имеет аргумента типа, вы должны всегда указывать тип явно - или <?>
, если вам действительно все равно.
Тем не менее, если вы не используете что-то конкретное для класса ArrayList
, вы должны использовать List<Cat>
, чтобы не связывать ваш код с конкретной реализацией List
.
Ответ 4
Как уже сказал Мэтт, использование наиболее распространенного интерфейса/суперкласса - лучший способ пойти сюда.
Обязательно всегда указывайте тип, который отображается в вашем списке, поэтому сделайте его List<Cat>
или даже List<? extends Cat>
Если в какой-то более поздний момент вы захотите заменить ArrayList
на, скажем, на LinkedList
, вам не придется изменять объявление, а только экземпляр.
Ответ 5
List
более гибкий, чем ArrayList
, List<Cat>
безопаснее, чем List
. поэтому List<Cat>
- хороший выбор.
Ответ 6
Прежде всего, List
- это интерфейс, а ArrayList
- это реализация интерфейса List
(на самом деле это подклассы AbstractList
и implements List
). Поэтому List cats = new ArrayList()
справедливо, так как ArrayList
is-a List
.
Для этого:
private List cats;
cats
становится сырым типом (нет ссылки на Generic Type для List
), он не был параметризован.
Ваше третье решение правильно (оно решает вашу проблему для варианта 1),
private ArrayList<Cat> cats;
вы ограничили общий тип E
для List<E>
типом Cat
. Следовательно, ваш экземпляр cats
действителен, так как общее ограничение является одинаковым.
Второе решение позволяет создать только ArrayList
of cats
. Другие 2 варианта позволяют вам создать экземпляр любого объекта, который есть-a List
, например. LinkedList
.