Get generic type for java.util.Map parameter

18,646

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);
        }
    }
}
Share:
18,646
Sebi
Author by

Sebi

Software Engineer

Updated on June 13, 2022

Comments

  • Sebi
    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
    Sebi almost 13 years
    Hi! 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
    Andreas Dolk almost 13 years
    Of 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
    Andreas Dolk almost 13 years
    Of 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
    Jonathan almost 9 years
    It 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
    Dave about 6 years
    The 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
    Dave about 6 years
    @Sergio - it is not the accepted answer for a reason
  • jacklehamster
    jacklehamster over 3 years
    The 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!