Каков корректный тип аргумента addAll (..) метод в наборах Java? Если я делаю что-то вроде этого:
List<? extends Map<String, Object[]>> currentList = new ArrayList<Map<String, Object[]>>();
Collection<HashMap<String, Object[]>> addAll = new ArrayList<HashMap<String, Object[]>>();
// add some hashmaps to the list..
currentList.addAll(addAll);
Я понимаю, что должен инициализировать обе переменные. Однако я получаю ошибку компиляции (от затмения):
Multiple markers at this line
- The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments (List<capture#2-of ? extends
Map<String,Object[]>>)
- The method addAll(Collection<? extends capture#1-of ? extends Map<String,Object[]>>) in the type List<capture#1-of ? extends Map<String,Object[]>> is not applicable for the arguments
(Collection<HashMap<String,Object[]>>)
что я делаю неправильно?
Вы можете вставлять только экземпляры T
в List
.
Тип Список extends Map
обозначает список неизвестного типа T
, который расширяет Map
. Например, он может обозначать List
. Очевидно, вы не можете вставить обычный HashMap
в такой список.
Вы, вероятно, захотите:
List<Map<String, Object[]>> currentList;
Или, если вы хотите быть действительно гибким, вы можете сделать:
List<? super Map<String, Object[]>> currentList;
Что позволит вам делать сумасшедшие вещи вроде:
currentList = new ArrayList<Map<? super String, ? extends Object[]>>();
Вы также можете прочитать FAQ по обобщениям Анжелики Лангер, в частности раздел о шаблонах .
Ваш вопрос в основном сводится к следующему:
public static <T extends Collection<?>> void foo(T t) {
T x = null;
x.addAll(t);
}
Это приведет к сбою, по сути, с той же ошибкой, которую вы описываете. Попробуйте что-нибудь в этом роде, чтобы исправить это.
public static <T extends Collection<Y>, Y> void foo(T t) {
T x = null;
x.addAll(t);
}
В качестве альтернативы, в приведенном выше примере вы можете изменить
List<? extends Map<String, Object[]>> currentList;
на
List<Map<String, Object[]>> currentList;
Generics довольно быстро становится волосатым, если вы пытаетесь начать передавать неуказанные типы.
Заменить extends
на super
.
Сам addAll ()
принимает ? расширяет аргумент T
, и это не сработает, когда T
равно ? расширяет Map
. С изменением станет эффективно ? расширяется? супер Карта
.
Но все же лучше просто удалить это ? расширяет
(или ? super
). В данном конкретном случае это лишнее. Просто используйте List
. Тогда addAll ()
будет эффективно принимать ? расширяет Map
.
В таком списке нельзя вызывать какой-либо метод с универсальными атрибутами. Собственно, что ? extends Foo
говорит, что это «что-то, что расширяет Foo
», но вы не знаете, что это такое. Когда этот тип возвращается, вы можете сказать, что возвращаемое значение - Foo
или какой-то подтип. Но для любого заданного значения вы не можете, чтобы оно соответствовало ? расширяет Foo
generic.
Вкратце: вам нужно изменить объявление currentList
или преобразовать его в List
( без дженериков) и жить с предупреждением или (если вы знаете, что делаете) подавите это.
просто запомните:
для ] extends ...>
, вы не можете помещать в него вещи (кроме null)
for super ...>
, вы не можете получить от него что-либо (кроме объекта)