Ответ 1
Вы не можете делать "put" с extends. Посмотрите Общие правила - Get and Put.
У меня есть вопрос Java о дженериках. Я объявил общий список:
List<? extends MyType> listOfMyType;
Затем в некотором методе я пытаюсь создать экземпляр и добавить элементы в этот список:
listOfMyType = new ArrayList<MyType>();
listOfMyType.add(myTypeInstance);
Где myTypeInstance
- это просто объект типа MyType
; он не будет компилироваться. В нем говорится:
Метод add (capture # 3-of? extends MyType) в типе List < capture # 3-of? extends MyType > не применимо для аргументов (MyType)
Любая идея?
Вы не можете делать "put" с extends. Посмотрите Общие правила - Get and Put.
Рассмотрим:
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
, что очень неправильно.
Вам не нужно использовать синтаксис захвата подстановки в вашем случае, просто объявив
List<MyType> listOfMytype;
должно быть достаточно. Если вы хотите точно знать, почему в Java Generics Tutorial есть больше, чем вы хотели бы узнать о эзотерическом безумии Java Generics. Страница 20 адресует ваш конкретный случай.
Что касается того, почему добавление с подстановочным знаком не работает, это связано с тем, что компилятор не может точно определить, какой подкласс MyType будет отображаться в каждом случае, поэтому компилятор испускает ошибку.
Здесь есть аналогичная тема: Как добавить элементы в общую коллекцию подстановочных знаков?
Чтобы узнать, как работают дженерики, посмотрите этот пример:
List<SubFoo> sfoo = new ArrayList<SubFoo>();
List<Foo> foo;
List<? extends Foo> tmp;
tmp = sfoo;
foo = (List<Foo>) tmp;
Дело в том, что это не было предназначено для локальных/членных переменных, но для сигнатур функций, почему это так задне-назад.
Я не знаю, действительно ли это вам поможет, но это то, что мне пришлось использовать, вызывая общий метод 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;
}
Кажется, вам нужно использовать параметризацию? войдите в список, чтобы получить результаты, а затем отнести список к ожидаемому типу возврата.
Я все еще ослеплен дженериками...