这两天有一个小需求:
在运行时取出 Map 对象实例的泛型参数。
Google 过后,第一条就是 StackOverflow 的相关问题:如何取出 Map 的泛型参数
在这做一下记录,原文问题及回答都非常有趣清晰。
问题:
public Object[] convertTo(Map source, Object[] destination) {
…
}
是否有可能通过反射来获取到 Map 的泛型参数?
回答 1:
被采纳的答案
对于任意的 Map<Key, Value>,要在运行时获取到它的 Key 和 Value 类型是不可能的。这是因为类型擦除。然而,可以在运行时通过 getClass() 检查 map 里每个对象的真实类型。再一次说明,这仍然不会告诉你 Key 和 Value 的类型。( 笔者注:考虑接口与实现的关系)
回答 2:
未被采纳
你可以轻松地通过反射获取到泛型参数。
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 的代码仅在特定情况下有效。