Reputation: 73
Why does the following line of code give an error in HashMap? It is not taking the wild card in the right hand side of the assignment.
Map<String,?> map=new HashMap<String,?>();
Upvotes: 1
Views: 9147
Reputation: 5593
In Java 7 and later you could just used the diamond notation as mentioned here:
https://docs.oracle.com/javase/tutorial/java/generics/types.html#diamond
Here's a quick example of using the diamond derived from the line of code shown in the question:
Map<String,?> map=new HashMap<>();
Upvotes: 1
Reputation: 122518
Just do:
class SuperBogusUnrelatedClass {}
// ...
Map<String, ?> map = new HashMap<String, SuperBogusUnrelatedClass>();
The above is correct, and 100% type-safe. Seriously, you can just put anything in there, even Math
. Why is it correct? Since it's a wildcard, it means it can be anything; you don't know what it is.
The ridiculousness of the above example also shows why this initialization is pretty much completely useless -- since the type parameter is unknown, you can't safely put any values (except null
) into the Map<String, ?>
. So your Map
will either have to be empty, or filled with entries whose value is null
. So basically, it is equivalent to a Set
.
Upvotes: 4
Reputation: 213391
You can't instantiate a parameterized type like that. A wildcard parameterized type is not a concrete type, so they could not appear in a new expression.
A wildcard parameterized type denotes a family of types comprising concrete instantiations of a generic type. The kind of the wildcard being used determines which concrete parameterized types belong to the family.
So, Map<String,?>
denotes the family of types, which can be Map<String, Object>
, Map<String, String>
, anything. You have to use the concrete type while creating an actual map.
So, you can do:
Map<String,?> map=new HashMap<String, String>();
Map<String,?> map=new HashMap<String, Object>();
But the issue with this declaration is that, you can't add anything to map except null
.
On the other hand, consider other types of wildcard - upper bounded, and lower bounded.
Map<String, ? extends Number>
The family of types denoted by this type are the concrete instantiation, where the value type is either Number
, or a subtype of Number
. So, for this one, the following are valid creation of concrete parameterized type:
Map<String, ? extends Number> map = new HashMap<String, Number>();
Map<String, ? extends Number> map = new HashMap<String, Integer>();
But again, issue here is you can't add anything in the map except null
or the value previously fetched from it.
Map<String, ? super Integer>
As you already know, you can't add anything to the wildcard parameterized type with unbounded wildcard, or upper bounded wildcard. There is a third type - lower bounded wildcard, which can be used if you are going to add something to the map. The family of type for the above parameterized type are the one that takes value of type Integer
or it's super type. So, you can instantiate it like this:
Map<String, ? super Integer> map = new HashMap<String, Number>();
Map<String, ? super Integer> map = new HashMap<String, Integer>();
Map<String, ? super Integer> map = new HashMap<String, Serializable>();
But there is another issue here. Although you can add a value to it, but when you fetch some value, you cannot be sure what type you get.
So, depending upon your requirement, you may have to use one or the other type of wildcard. May be some more information in the question might help you. But, in general just remember, you can't create an object of wildcard parameterized type, but only concrete parameterized type.
Upvotes: 18
Reputation: 379
You can not use a wild card while instantiating an object of a concrete class.
Upvotes: 2
Reputation: 8483
You are instantiating an object by whose type is a type parameter.It is not possible.
because the compiler does not know how to create objects of an unknown type.
More details Can I create an object whose type is a type parameter?
Upvotes: 0
Reputation: 83577
Since you are creating a HashMap
object, you must specify all of the generic parameters.
Upvotes: 1