I am trying to make a method call like this,
public class GenericsTest<T> {
public static <T> Map<String, T> createMap(Class<? extends Map<String, T>> clazz) {
return null;
}
public static void main(String[] argv) {
Map<String, Integer> result = createMap(TreeMap.class);
}
}
But I am getting this error,
<T>createMap(java.lang.Class<? extends java.util.Map<java.lang.String,T>>) in test.GenericsTest<T> cannot be applied to (java.lang.Class<java.util.TreeMap>)
How to fix this problem?
Map<String, Integer> instance = new TreeMap<String, Integer>();
@SuppressWarnings("unchecked")
Map<String, Integer> map =
createMap((Class<? extends Map<String, Integer>>)instance.getClass());
map.put("x", 1);
System.out.println("THIS IS x: " + map.get("x"));
This will appropriately print out 1. The implementation of the method is most likely
try
{
return clazz.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
A better implementation of their API would be for them to ask you for the type, T
, and for them to give back a Map
of their choosing instead of asking you for all of the details. Otherwise, as long as they are not filling in the Map
with any data, you can instantiate a Map
with the generic type argument yourself like so:
public static <T> Map<String, T> getMap()
{
return new TreeMap<String, T>();
}
You can then access that without a warning:
// note the lack of type arguments, which are inferred
Map<String, Integer> instance = getMap();
// alternatively, you could do it more explicitly:
// Map<String, Integer> instance = ClassName.<Integer>getMap();
There's really no reason for them to ask you for the Class
type of your Map
except to give you back an exact match to the implementation (e.g., if you stick in a HashMap
, then you will get back a HashMap
, and if you stick in a TreeMap
, then you will get back a TreeMap
). However, I suspect that the TreeMap
will lose any Comparator
that it was constructed with, and since that is an immutable (final
) field of TreeMap
, then you cannot fix that; that means that the Map
is not the same in that case, nor is it likely to be what you want.
If they are filling in the Map
with data, then it makes even less sense. You could always pass in an instance of a Map
to fill, or have them return a Map
that you can simply wrap (e.g., new TreeMap<String, Integer>(instance);
), and they should know which Map
offers the most utility to the data.
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