2016-06-01 4 views
4

Не понимаю generic wildcard bounderies Ussage.
Не могли бы вы объяснить, почему processList работает довольно хорошо, а processMap с ошибкой компиляции в следующем примере? Как я должен изменить подпись processMap, чтобы заставить его работать с обоими Map<String, List<String>> и Map<String, List<Object>>Общие подстановочные знаки в сложных типах

public void processList(List<? extends Object> list) { 
} 

public void processMap(Map<String, List<? extends Object>> map) { 
} 

public void f() { 
    List<String> list = new ArrayList<>(); 
    Map<String, List<String>> map = new HashMap<>(); 

    processList(list); // OK 
    processMap(map); // ERROR 
} 

Двигаясь общее определение типа от типа аргумента метода к методу paramether сделал трюк

public void processMap(Map<String, List<? extends Object>> map) 
public <T extends Object> void processMap(Map<String, List<T>> map) 

Я бы теперь хотелось узнать разницу между ними. Перемещено на another thread.

+0

Я не знаю, прав я или нет, но, похоже, java-компилятор не может разрешить или преобразовать тип коллекции, используемый в качестве ключа к коллекции карт, определенной в проблеме. Я говорю об этом, потому что когда я изменяю подпись функции как «public static void processMap (Map > map)', он отлично работает. Похоже, что существует большая разница между ' и' 'при использовании в таких объявлениях. Его многоуровневая концепция подстановочных знаков. – qwerty

ответ

1

Вы можете заставить его работать, если вы устраните шаблон. То есть создать обобщенную функцию с именем типа: <T extends Object>

public <T extends Object> void processMap(Map<String, List<T>> map) { 
} 

public void processList(List<? extends Object> list) { 
} 

public void f() { 
    List<String> list = new ArrayList<>(); 
    Map<String, List<String>> map = new HashMap<>(); 

    processList(list); // OK 
    processMap(map); // OK now 
    processMap(new HashMap<String, List<Integer>>()); // this is OK too 
} 

К сожалению, я не могу объяснить, почему функция с групповым символом не работает.

+0

Я думаю, причина, почему _why_ это работает, имеет какое-то отношение к [подстановочный знак] (https://docs.oracle.com/javase/tutorial/java/generics/capture.html). –

+0

Просто выложил ту же самую ... только разницу: нет необходимости помещать 'extends Object' там. Любой T, который вы когда-либо будете использовать, будет расширять Object, не сообщая компилятору ;-) – GhostCat

+0

Да. Использование '' теперь в порядке. 'extends' хорош для таких вещей, как' ' –

0
Map<String, List<? extends Object>> map = new HashMap<>(); 

сделайте вышеуказанное изменение в методе f() и оно работает. Компилятор Java проверяет тип переменной, поэтому оба должны быть одинаковыми, я могу ошибаться.

1

Половина ответа: для меня компилируется следующий код.

Отсутствует: хорошее объяснение причин, по которым работает именованный Т; но неназванный? не.

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