4

in java, what is wrong with this assignment:

Map<String, Object> mObj = new HashMap<String, String[]>();

I get:

error: incompatible types: HashMap<String,String[]> cannot be converted to Map<String,Object>

Since String[] is an Object, that should work. If I cast to an unparameterized Map like this: Map<String, Object> mObj = (Map) new HashMap<String, String[]>();, it is working but of course, I get a warning and it is dirty.

Further more, I feel that my first assignment should work.

Thank you !

PS: I cannot simply change new HashMap<String, String[]>(); to new HashMap<String, Object>(); because in reality, I call a method that returns a Map<String, String[]>(); and of course, I cannot change this method. Thank you again.

ncenerar
  • 1,487
  • 12
  • 25

3 Answers3

9

The error is is because generics do not support subtyping. Number a = new Integer(5) is valid case. But once you put generics it gives compilation error ArrayList<Number> a = new ArrayList<Integer>() is not allowed. See if this link helps https://dzone.com/articles/5-things-you-should-know-about-java-generics to understand some guidelines on Generics.

  • Great link, I didn't knew how generics works and what were multiple bounds, and also, why you can't sub-type. But you can use wild card with extends and super as mentionned in the link, which might work here. – Asoub Dec 16 '15 at 13:45
6

Lets' see what could happen if what you wrote would be possible:

HashMap<String, String[]> foo = new HashMap<String, String[]>();
Map<String, Object> bar = foo;
bar.put("key",new Object());
String[] baz = foo.get("key"); // <-- ClassCastException

See the problem? A series of normal, mundane operations will cause ClassCastException in a place where you would expect it wouldn't be possible to emit one.

Edit: To summarize, Map<String, Object> is not a supertype of Map<String, String>, Map<String, Object[]> or Map<String, String[]>, so the assignment will not work, as the types aren't compatible. This is where wildcards come in; see this answer and this one too

Community
  • 1
  • 1
Tassos Bassoukos
  • 15,613
  • 2
  • 31
  • 38
  • You're absolutely right but since I can bypass my error by casting to unparameterized `Map`, I still have the power to mess up the poor normal mundane operations ;) Don't you think it would have been more relevant to get only a unchecked warning instead of an incompatible types error ? – ncenerar Dec 16 '15 at 14:29
1

Do this:

Map<String, ? extends Object> mObj = new HashMap<String, String[]>();

But I can't tell you why your solution doesn't work.

Richard Loth
  • 69
  • 1
  • 6