这两天有一个小需求:
运行时
取出 Map对象实例
的泛型参数。 Google过后,第一条就是StackOverflow的相关问题: 如何取出Map的泛型参数
在这做一下记录,原文问题及回答都非常有趣清晰。
public Object[] convertTo(Map source, Object[] destination) { ... }
是否有可能通过反射来获取到Map的泛型参数?
被采纳的答案
对于任意的 Map<Key, Value>
,要在 运行时
获取到它的 Key
和 Value
类型是不可能的。这是因为 类型擦除
。
然而,可以在 运行时
通过 getClass()
检查map里每个对象的真实类型。再一次说明,这仍然不会告诉你 Key
和 Value
的类型。(笔者注:考虑接口与实现的关系)
未被采纳
你可以轻松地通过反射获取到泛型参数。
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(); } }
回答2贴出的代码非常有效,能够完整地取出 Map<Key, Value>
的泛型参数。于是有人质疑为何回答2没有被采纳。
于是有人解释道:
被采纳的回答1才是正确的。回答2只是抽取了Field字段中的类型声明。这与 在运行时获取对象实例的泛型参数
是不一样的操作。尤其题主的代码中的 Map
并没有带任何泛型参数,这种情况甚至无法从 参数声明
中获取泛型。所以回答2的代码仅在特定情况下有效。