如何在 Java 中使用泛型类型获取类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11554192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get class with generics types in Java
提问by ZZ Coder
I am trying to make a method call like this,
我正在尝试进行这样的方法调用,
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);
}
}
But I am getting this error,
但我收到这个错误,
<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>)
How to fix this problem?
如何解决这个问题?
采纳答案by pickypg
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"));
This will appropriately print out 1. The implementation of the method is most likely
这将适当地打印出 1. 方法的实现是最有可能的
try
{
return clazz.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
A better implementation of their API would be for them to ask you for the type, T
, and for them to give back a Map
of their choosing instead of asking you for all of the details. Otherwise, as long as they are not filling in the Map
with any data, you can instantiate a Map
with the generic type argument yourself like so:
他们的 API 的更好实现是让他们询问您的类型,T
并让他们返回Map
他们选择的a ,而不是询问您所有的细节。否则,只要它们没有填充Map
任何数据,您就可以Map
像这样自己使用泛型类型参数实例化 a :
public static <T> Map<String, T> getMap()
{
return new TreeMap<String, T>();
}
You can then access that without a warning:
然后您可以在没有警告的情况下访问它:
// 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();
There's really no reason for them to ask you for the Class
type of your Map
except to give you back an exact match to the implementation (e.g., if you stick in a HashMap
, then you will get back a HashMap
, and if you stick in a TreeMap
, then you will get back a TreeMap
). However, I suspect that the TreeMap
will lose any Comparator
that it was constructed with, and since that is an immutable (final
) field of TreeMap
, then you cannot fix that; that means that the Map
is not the same in that case, nor is it likely to be what you want.
他们真的没有理由问你你的Class
类型,Map
除了给你一个完全匹配的实现(例如,如果你坚持 a HashMap
,那么你会得到 a HashMap
,如果你坚持 a TreeMap
,那么你会回来的TreeMap
)。但是,我怀疑TreeMap
将丢失Comparator
它构建的任何内容,并且由于这是一个不可变的 ( final
) 字段TreeMap
,因此您无法修复它;这意味着Map
在那种情况下是不一样的,也不可能是你想要的。
If they are filling in the Map
with data, then it makes even less sense. You could always pass in an instance of a Map
to fill, or have them return a Map
that you can simply wrap (e.g., new TreeMap<String, Integer>(instance);
), and they should know which Map
offers the most utility to the data.
如果他们正在填写Map
数据,那么就更没有意义了。你总是可以传入一个 a 的实例Map
来填充,或者让他们返回一个Map
你可以简单地包装的(例如,new TreeMap<String, Integer>(instance);
),他们应该知道哪个Map
为数据提供了最多的效用。