Причина в том, что ?
в List<?>
может быть «чем угодно», но отличается «что угодно» в каждой записи Map
. То есть, он принимал бы List<String>
в одной записи и List<Integer>
в другой.
Но вы проходите в Map
, у которого есть тот же тип из List
в каждой записи, поэтому тип не связан таким же образом или в той же степени для свободы.
«Исправить» - это блокировка типа для определенного типа, но все же «все» - только то же «ничего» в каждой записи, набрав метод:
public static <T> void accept(Map<String, List<T>> multiMap) // complies
, или если вашему методу действительно не нужно знать тип , используйте шаблон для обертывания типа:
public static void accept(Map<String, ? extends List<?>> multiMap) // compiles
Эта последняя версия работает, потому что тип списка, хотя и является подстановочным знаком, привязан к неизвестному, но согласованный , тип при вызове.
Я нахожу, что типизированная версия легче читать (и код), а тип используется для использования, если вы позже решите, что ваш метод должен знать тип .