2013-04-12 2 views

ответ

10

Это похоже ошибка, как

List<Animal> list = new ArrayList<Dog>(); 

Parameterized типа должны быть одного типа на обоих концах. Концепции наследования (IS-A) нет. Если вы все еще хотите использовать его, используйте подстановочный знак (?) С ключевым словом extend/super, который разрешен только в левой части знака равенства.

List<Animal> list = new ArrayList<Dog>(); // is not allowed 

но

Animal[] animal = new Dog[10]; //is allowed 
animal[0] = new Dog(); // is allowed 

, где он будет позже и не в состоянии бросить исключение, если кто-то пытается добавить Cat (расширяет животных) объекта.

animal[1] = new Cat(); //compiles fine but throws java.lang.ArrayStoreException at Runtime. 

Запомнить animal[1] или animal[index] держит reference собак. Таким образом, Dog ссылочная переменная может ссылаться на Dog объект не Cat объект.

Так, чтобы избежать такого сценария, JSL внесла такие изменения в список обобщений/Collection. Этот ответ также применим для вашего вопроса (Map).
Параметрированный тип должен быть одного типа с обоих концов.

List<Animal> list = new ArrayList<Animal>(); 
20

Дженерики не являются ко-вариантами. Вы можете использовать:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>(); 
^                ^
--------------^------------------- becomes ------^    | 
       -----------------must remain as type --------------- 

Хотя Map на внешней левой части задания может «стать» HashMap как назначено, то же самое не может быть применен к любым типам, которые появляются в качестве родовых параметров.

Edit:

Как отметил @Keppil, вы можете использовать ограниченный синтаксис подстановки:

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>(); 

Обратите внимание, что этот синтаксис не позволит записи, которые будут добавлены к карте, но полезно как тип, который должен быть передан методам и из них.

Некоторые ссылки:

+3

Вы также можете использовать 'Map > myMap = new HashMap >(); ' – Keppil

+2

@Reimeus мне будет полезно другое объяснение .. –

2

Попробуйте это:

Map<Integer, HashMap<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>(); 
3

вам нужно что-то вроде т его:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>(); 
myMap.put(1, new HashMap<String, Integer>()); 
6

Попробуйте

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>(); 

Это проще для объяснения на более простом примере

Set<Number> set = new HashSet<Integer>(); 

не допускается, потому что тогда вы могли бы добавить Double к HashSet из Целые

set.add(1.0) 

Записка th в

Set<? extends Number> set = new HashSet<Integer>(); 

не позволяет добавить что-нибудь, но null к набору. Но вы можете только читать номера из него

Вы можете найти более подробную информацию здесь http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

3

Map<String, Integer> не такой же, как HashMap<String, Integer>. Это проблема.

На самом деле HashMap реализует интерфейс карты. Так что это должно быть ? extends Map<String, Integer> с левой стороны

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