When I try to create object as below :
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
What is wrong syntactically, can any one explain me?
Generics are not co-variant. You can use:
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
^ ^
--------------^------------------- becomes ------^ |
-----------------must remain as type ---------------
While the Map
on the outer left hand side of the assignment can "become" a HashMap
as assigned, the same cannot be applied to any types that appear as generic parameters.
Edit:
As noted by @Keppil, you can use the bounded wildcard syntax:
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Note that this syntax will not allow entries to be added to the map but is useful as a type to be passed to and from methods.
Some references:
It is similar error like
List<Animal> list = new ArrayList<Dog>();
Parameterized type should be of same type at both end. There is no inheritance (IS-A) concept. If you still want to use it then use wildcard(?) with extend/super keyword which is allowed only at left side of the equals sign.
List<Animal> list = new ArrayList<Dog>(); // is not allowed
but
Animal[] animal = new Dog[10]; //is allowed
animal[0] = new Dog(); // is allowed
where it will later fail and throw exception if somebody tries to add Cat
(extends Animal) object.
animal[1] = new Cat(); //compiles fine but throws java.lang.ArrayStoreException at Runtime.
Remember animal[1]
or animal[index]
is holding reference
of Dog. So Dog
reference variable can refer to Dog
object not Cat
object.
So to avoid such scenario, JSL have made such changes in generics list/Collection. This answer is also applicable for your question(Map
).
Parameterized type should be of same type at both end.
List<Animal> list = new ArrayList<Animal>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With