Reputation: 21
I have two maps Something1
and Something2
. Both extend the Class Something
.
Map<Class<? extends Something1>, String> m1
Map<Class<? extends Something2> ,String> m2
I want to create a more generic map m3
to which I can assign m1
or m2
like this:
Map<Class<? extends Something>, String> m3 = m1;
However I get the following exception:
Type mismatch: cannot convert from Map<Class<? extends Something1>, String> to Map<Class<? extends Something>, String>
I also tried using Class<?>
but it doesn't seem to work.
What am I doing wrong ?
Upvotes: 2
Views: 65
Reputation: 122449
Non-wildcard type arguments must be exactly the same to be compatible. Class<? extends Something1>
is not exactly the same as Class<? extends Something>
(even though one is a subtype of the other), and therefore, a Map
of one is not compatible with a Map
of the other.
If you want a type that can accept Map
s with different type arguments, you need a wildcard at the top level (though note that this will effectively make the Map
read-only):
Map<? extends Class<? extends Something>, String> m3 = m1;
Upvotes: 0
Reputation: 19221
That is not possible. Consider the following:
Map<Class<? extends Something1>, String> m1 = new HashMap<>();
m1.put(Something1.class, "Something1"); // OK
m1.put(Something2.class, "Something2"); // Error
So, you can't put Something2
as the key.
The other way around:
Map<Class<? extends Something2>, String> m2 = new HashMap<>();
m2.put(Something1.class, "Something1"); // Error
m2.put(Something2.class, "Something2"); // OK
Here, you can't put Something1
as the key.
But, if you create a version that uses the base class as the wildcard it works. Check this out:
Map<Class<? extends Something>, String> m = new HashMap<>();
m.put(Something1.class, "Something1"); // OK
m.put(Something2.class, "Something2"); // OK
Your problem is then that you are trying to assign a more specific type to the generic type. Like this:
m = m1; // Boom, but why?
Why does that not work. Well, it is because if you allow that assignment you would be able to do this:
m.put(Something2.class, "Something2");
Which obviously would not be ok since then you would put Something2
as the key for a Something1
-type Map.
Upvotes: 2