2013-10-02 2 views
0

Я пытаюсь создать общий список, который будет содержать объекты любого типа, которые наследуются от Object (я предполагаю, что каждый объект имеет объект типа).Создание общего списка объекта типа и добавление строки

Но в нижеприведенном случае, когда я пытаюсь добавить строку (наследуется от Object), он показывает ошибку в Затмении

Error:-The method add(capture#1-of ? extends Object) in the type List<capture#1-of ? extends Object> is not applicable for the arguments (String) 


List<? extends Object> alist = new ArrayList<Object>(); 
alist.add("USA"); 

Может кто-то объяснить, почему я получаю эту ошибку?

ответ

6

Причина в том, что <? extends Object> может представлять любой подкласс Object, который, вероятно, не связан с String. Это может быть List<Integer>.

List<? extends Object> alist = new ArrayList<Integer>(); // works 
alist.add("USA"); // Should you be allowed to do this? No! 

Для безопасности типа, вы не должны быть в состоянии выполнить такую ​​операцию add. По этой причине эта операция запрещена.

Обойти является устранение подстановочные в объявлении переменной:

List<Object> alist = new ArrayList<Object>(); 

Теперь любой Object или подкласс может быть передан add.

0

Проблема с тем, что вы пытаетесь следующая

List<? extends Object> alist = getList(); // returns a List<Dog> 
alist.add("USA"); // would fail at runtime 

Так что компилятор не позволяет добавлять к любому List связанного шаблона.

0

Точная фраза ? extends Object означает, что это также ОК , чтобы добавить всех членов коллекции с элементами любого типа, являющегося подтипом объекта.

Поскольку все типы наследования объекта вы можете написать просто List<Object>

List<Object> alist = new ArrayList<Object>(); 
alist.add("USA"); 
0

Ваш случай является еще одним примером, где эффективная Java-PECS мнемонические может помочь.

Ваш alist является потребителем, то есть вы хотите, чтобы он (потреблял) добавлял к нему новые объекты. Из PECS, то вы должны использовать Collection<? super Thing>:

List<? super Object> alist = new ArrayList<Object>(); 
alist.add("USA"); 

Таким образом, вы всегда будете иметь возможность .add() любой Object в alist. (И потому, что "USA" является Object, вы можете добавить его без проблем.)

Обратите внимание, что, используя super в вашем типе ...

List<? super Object> alist = new ArrayList<Integer>(); // notice <Integer> here 
alist.add("USA"); 

...первая строка по праву даст ошибку, так как Integer не является супертипом Object.

Конечно, естественно, что это немного запутывает, потому что Object не имеет суперкласса, и класс не является суперклассом Object. В связи с этим, эффективно, единственно возможной правой стороной для назначения List<? super Object> alist = является List<Object> (или любой класс, реализующий List, из-за полиморфизма).

Read more about PECS here.

Ознакомьтесь с разъяснением PECS от book Effective Java here.

Смежные вопросы