我想尝试这样的方法调用,
public class GenericsTest<T> {
public static <T> Map<String, T> createMap(Class<? extends Map<String, T>> clazz) {
return null;
}
public static void main(String[] argv) {
Map<String, Integer> result = createMap(TreeMap.class);
}
}
Run Code Online (Sandbox Code Playgroud)
但我收到这个错误,
<T>createMap(java.lang.Class<? extends java.util.Map<java.lang.String,T>>) in test.GenericsTest<T> cannot be applied to (java.lang.Class<java.util.TreeMap>)
Run Code Online (Sandbox Code Playgroud)
如何解决这个问题?
Map<String, Integer> instance = new TreeMap<String, Integer>();
@SuppressWarnings("unchecked")
Map<String, Integer> map =
createMap((Class<? extends Map<String, Integer>>)instance.getClass());
map.put("x", 1);
System.out.println("THIS IS x: " + map.get("x"));
Run Code Online (Sandbox Code Playgroud)
这将适当地打印出 1. 该方法的实现最有可能
try
{
return clazz.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)
他们的 API 的更好实现是让他们询问您的类型,T并让他们返回Map他们选择的类型,而不是询问您所有的详细信息。否则,只要它们没有填充Map任何数据,您就可以Map自己使用泛型类型参数实例化 a,如下所示:
public static <T> Map<String, T> getMap()
{
return new TreeMap<String, T>();
}
Run Code Online (Sandbox Code Playgroud)
然后您可以在没有警告的情况下访问它:
// note the lack of type arguments, which are inferred
Map<String, Integer> instance = getMap();
// alternatively, you could do it more explicitly:
// Map<String, Integer> instance = ClassName.<Integer>getMap();
Run Code Online (Sandbox Code Playgroud)
他们确实没有理由询问Class您的类型Map,除了给您返回与实现完全匹配的结果(例如,如果您坚持 a HashMap,那么您将返回 a HashMap,如果您坚持 a TreeMap,那么您将返回 a TreeMap)。但是,我怀疑 将会TreeMap丢失Comparator它所构造的任何内容,并且由于这是 的不可变 ( final) 字段TreeMap,因此您无法修复它;这意味着Map在这种情况下 是不一样的,也可能不是你想要的。
如果他们用数据填充Map,那就更没有意义了。您始终可以传入 a 的实例来Map填充,或者让他们返回Map您可以简单包装的 a (例如,new TreeMap<String, Integer>(instance);),并且他们应该知道哪个Map为数据提供了最大的实用性。