I have a method that returns a map
defined as:
public Map<String, ?> getData();
The actual implementation of this method is not clear to me, but, when I try to do:
obj.getData().put("key","value")
I get following compile time error message:
The method put(String, capture#9-of ?)
in the type Map
is not applicable for the arguments
(String, String)
What is the problem? Is String
not of type anything?
Thanks in advance.
The wildcard means "the value type parameter could be anything" - it doesn't mean "you can use this as if it were anything you want it to be". In other words, a Map<String, UUID>
is valid as a Map<String, ?>
- but you wouldn't want to be able to put a String value into it.
If you want a map which can definitely accept string values, you want:
Map<String, ? super String>
The return type of
Map<String, ?>
is the same as
Map<String, ? extends Object>
The means that the concrete type returned could be a Map<String, AnyClass>
. You can't put a String
into an AnyClass
, hence the error.
A good general principle is to not use wildcards in method return types.
Map<String, ?>
is a short form of Map<String,? extends Object>
and doesn't mean that anything can be added as value. It says that the Map-object can have any generic value type extending Object
.
This means that the Map object can be a HashMap<String, String>
or a HashMap<String, Integer>
as well. Because the compiler can't check which value types will be accepted, he won't let you call methods with the value type as a parameter.
Note:
- You can call methods with the value type as a return value, because everything must extend Object (? extends Object)
- A
Map<String, ? super String>
will have the opposite effect: You can always use a String as parameter, but the return-type is unclear.
Try this:
public Map<String, Object> getData();
[EDIT] This is really wrong... I understood.
My first answer was:
That's java : String is not an object.
Try with
obj.getData().put("key",new String("value"));
But String extends Object... while I thought String was a primitive. I learned something ^^