Я хотел бы использовать карту с различными списками в качестве значений:
Map<String, List<Integer>> ml;
Map<String, ?> ml2 = ml; // OK
Map<String, List<?>> ml3 = ml; // Type mismatch
Почему последняя строка недействительна?
Недействительно, так как если бы оно было действительным, вы могли бы добавить нецелые списки в ml
.
Пример (недействителен):
Map<String, List<Integer>> ml;
Map<String, List<?>> ml3 = ml;
ml3.put("strings", Arrays.asList("evil","string"));
List<Integer> l = ml.get("strings"); //see how this is going to fail?
Почему Map<String, ?> ml2 = ml;
действует? Это потому, что использование подстановочного знака говорит компилятору не допускать добавления новых элементов, т.е. ml2.put("strings", Arrays.asList("evil","string"));
не будет разрешено (компилятор не выполняет проверку типа, он просто видит подстановочный знак и знает, что вы не должны вызывать этот метод.
Map<String, ?>
возьмет карту строк для любого объекта, List of Integer может быть сопоставлен этим шаблоном. Однако List of Integer не соответствует списку? (Список любого объекта), поскольку List of Integer может принимать только объекты Integer.
Map<String, List<?>>
- это карта, в которую можно поместить строку и список чего угодно.Map<String, List<Integer>>
- это карта, в которую можно поместить только строку и список целых чисел.