2009-05-27 3 views
36

У меня есть вопрос Java о дженериках. Я объявил общий список:Список <? extends MyType>

List<? extends MyType> listOfMyType; 

Тогда в некотором методе я пытаюсь создать экземпляр и добавлять элементы в этот список:

listOfMyType = new ArrayList<MyType>(); 
listOfMyType.add(myTypeInstance); 

Где myTypeInstance только объект типа MyType; он не будет компилироваться. Он говорит:

Метод дополнение (? Захват # 3-оф расширяет MyType) в списке Типа < захвата # 3-в ? extends MyType> не применимо для аргументов (MyType)

Любая идея?

ответ

29

Вы не можете сделать «положить» с расширением. Посмотрите на Generics - Get and Put rule.

+9

Как говорит Джош Блох: "Помните, PECS: Производитель Расширяет, Consumer Super." Поскольку listOfMyType является потребителем (вы добавляете к нему), 'super' является допустимым, а' extends' - нет. –

+0

Ссылки сейчас сломаны. –

+0

Точка педантизма: вы можете 'put'' null' с расширением ".Также вы можете захватить тип и «поставить» ссылки, которые вы получили ранее ». –

4

Вы не должны использовать подстановочные синтаксис захвата в вашем случае, просто объявляя

List<MyType> listOfMytype; 

должно быть достаточно. Если вы хотите точно знать, почему, Java Generics Tutorial имеет больше, чем вы хотели бы узнать об эзотерическом сумасшествии Java Generics. В вашем конкретном случае.

Что касается того, почему добавление с подстановочным знаком не работает, это связано с тем, что компилятор не может точно определить, какой подкласс MyType будет отображаться в каждом случае, поэтому компилятор испускает ошибку.

22

Рассмотрим:

class MySubType extends MyType { 
} 

List<MySubType> subtypeList = new ArrayList<MySubType>(); 
List<? extends MyType> list = subtypeList; 
list.add(new MyType()); 
MySubType sub = subtypeList.get(0); 

sub теперь содержит MyType что очень неправильно.

+0

Не следует ли «list.get (0);» на самом деле быть "subtypeList.get (0);" ? – Zds

+0

@ Zds Yup, исправлено. Благодарю. –

2

Существует аналогичная нить здесь: How can elements be added to a wildcard generic collection?

Чтобы получить представление о том, как дженерики работы проверить этот пример:

List<SubFoo> sfoo = new ArrayList<SubFoo>(); 
    List<Foo> foo; 
    List<? extends Foo> tmp; 

    tmp = sfoo; 
    foo = (List<Foo>) tmp; 

Дело в том, что не был предназначен для локального/члена переменные, но для сигнатур функций, поэтому это так задне-назад.

2

Я не знаю, если это действительно поможет вам, но это то, что я должен был использовать при вызове универсального метода Spring Framework и хочу вернуться также общий список:

public <T> List<T> findAll(String tableName,Class<?> table) { 
    String sql = "SELECT * FROM "+ tableName ; 
    List<?> entities = getSimpleJdbcTemplate().query(sql, 
      ParameterizedBeanPropertyRowMapper.newInstance(table)); 
      return (List<T>) entities; 
} 

КАЖЕТСЯ потребность параметризации вы можете использовать? войдите в список, чтобы получить результаты, а затем отнести список к ожидаемому типу возврата.

Иам еще ослеплен дженериков ...

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