2011-05-27 218 views
5
public Object[] convertTo(Map source, Object[] destination) { 
    ... 
} 

是否有可能通过反射找出我的Map参数的泛型类型(键/值)?获取java.util.Map的泛型类型参数

+0

你为什么要这么做?那是这种方法的目的? – helpermethod 2011-05-27 06:53:42

+1

我并不完全理解这个问题,但我认为答案可能在[Collection.toArray()]的代码中(http://download.oracle.com/javase/6/docs/api/java/util /Collection.html#toArray%28T[]%29)。 – Augusto 2011-05-27 06:55:23

+0

您的实际地图没有泛型类型,它当前将'Object'映射到'Object'。 – 2011-05-27 07:19:33

回答

8

给定Map<Key,Value>,在运行时不可能计算出KeyValue。这是由于type erasure(另请参见Wikipedia)。

但是,可以检查映射中包含的每个对象(键或值),并调用它们的getClass()方法。这会告诉你该对象的运行时类型。请注意,这仍然不会告诉你有关编译类型KeyValue的任何信息。

+3

*当然,如果地图是空的,它不起作用*当然,如果泛型类型是接口类或抽象类,它会给出错误的结果...... – 2011-05-27 07:16:49

+1

实际上,如果Map是子类,ex, 'StringMap扩展Map {...'。查看[TypeTools](https://github.com/jhalterman/typetools)以获取如何提取类型参数的示例。 – Jonathan 2015-07-26 02:27:55

1

您可以通过获取每个元素并在每个键/值对象上调用getClass来检查源对象中的条目。当然,如果地图没有在源处通用化,那么不能保证其中的所有键/值都是相同的类型。

+0

嗨!是的,这可以工作..但我也有相反的方法,我必须从Object []转换为Map。在那里我不能使用这种方法。 – Sebi 2011-05-27 07:00:55

+0

*当然*它不工作,如果地图是空的*当然*它会给出错误的结果,如果泛型类型是接口或抽象类... – 2011-05-27 07:17:15

1

你不能从地图在运行时的值类型,但也许你可以从destination阵列得到它(只要它不是null。)

public <V> V[] convertTo(Map<?,V> source, V[] destination) { 
    return source.values().toArray(destination); 
} 
1

这样就可以得到地图的关键字和值的类型

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); 
     } 
    } 
} 
10

我知道这个问题是旧的,但最好的答案是错误的。
您可以通过反射轻松获取泛型。下面一个例子:

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(); 
    } 
} 

这将让你的输出:
Key: class java.lang.String
Value: class java.lang.Integer

+1

这应该是公认的答案 – Sergio 2015-12-23 19:00:36

+0

接受的答案是正确的。您正在检索声明的通用类型。这与检索通用类型信息已被擦除的对象实例的编译时泛型类型不是同一个问题。具体来说,OP输入Map参数时没有任何通用参数(隐式地),从中可以恢复这些信息。您的回答虽然对您的具体情况有用,但并未解决问题。 – Dave 2018-03-06 01:55:00

+0

@Sergio - 这不是一个理由的接受答案 – Dave 2018-03-06 01:55:49