Get generic type for java.util.Map parameter
Solution 1
Given a Map<Key,Value>
, it isn't possible to figure out Key
and Value
at runtime. This is due to type erasure (also, see Wikipedia).
It is, however, possible to examine each object (key or value) contained in the map, and call their getClass()
method. This will tell you the runtime type of that object. Note that this still won't tell you anything about the compile-type types Key
and Value
.
Solution 2
I know this question is old, but the best answer is wrong.
You can easily get the generic types via reflections. Here an example:
private Map<String, Integer> genericTestMap = new HashMap<String, Integer>();
public static void main(String[] args) {
try {
Field testMap = Test.class.getDeclaredField("genericTestMap");
testMap.setAccessible(true);
ParameterizedType type = (ParameterizedType) testMap.getGenericType();
Type key = type.getActualTypeArguments()[0];
System.out.println("Key: " + key);
Type value = type.getActualTypeArguments()[1];
System.out.println("Value: " + value);
} catch (Exception e) {
e.printStackTrace();
}
}
This will get you the output:
Key: class java.lang.String
Value: class java.lang.Integer
Solution 3
You cannot get the value type from the map at run-time, but maybe you can get it from the destination
array (as long as it is not null
.)
public <V> V[] convertTo(Map<?,V> source, V[] destination) {
return source.values().toArray(destination);
}
Solution 4
You can inspect the Class for entries in the source object by getting each element, and calling getClass on the key/value object for each. Of course, if the map wasn't genericised at source then there's no guarantee that all the keys/values in it are of the same type.
Solution 5
In this way you can get the type of the key and value of a map
public class Demo
{
public static void main(String[] args)
{
Map map = new HashMap<String, Long>();
map.put("1$", new Long(10));
map.put("2$", new Long(20));
Set<?> set = map.entrySet();
Iterator<?> iterator = set.iterator();
String valueClassType="";
while (iterator.hasNext())
{
Map.Entry entry = (Entry) iterator.next();
valueClassType = entry.getValue().getClass().getSimpleName();
System.out.println("key type : "+entry.getKey().getClass().getSimpleName());
System.out.println("value type : "+valueClassType);
}
}
}
Comments
-
Sebi almost 2 years
public Object[] convertTo(Map source, Object[] destination) { ... }
Is there a possibility to figure out the generic types (key / value) of my Map parameter via Reflection?
-
Sebi almost 13 yearsHi! Yes, that could work.. But I also have the reverse method, where I have to convert from Object[] to Map. And there I can't use this approach.
-
Andreas Dolk almost 13 yearsOf course it doesn't work if the map is empty an of course it gives wrong results if the generic types are either interfaces or abstract classes...
-
Andreas Dolk almost 13 yearsOf course it doesn't work if the map is empty an of course it gives wrong results if the generic types are either interfaces or abstract classes...
-
Jonathan almost 9 yearsIt actually is possible if the Map is subclassed, ex,
StringMap extends Map<String, String> { ...
. Check out TypeTools for an example of how to extract the type args. -
Dave about 6 yearsThe accepted answer is correct. You are retrieving the generic type of the declaration. This is not the same problem as retrieving the compile-time generic type of an object instance for which the generic type information has been erased. Specifically the OP typed the Map parameter without any generic parameters (implicitly <Object,Object>) from which this information could be recovered. Your answer, while useful for your specific case, does not address the question.
-
Dave about 6 years@Sergio - it is not the accepted answer for a reason
-
jacklehamster over 3 yearsThe accepted answer might be correctly answering the stated question, but this answer does help solving some issues where the accepted answer did not. So thanks!