如何在Java中使用泛型类来获得类 [英] How to get class with generics types in Java
问题描述
public class GenericsTest< T>< p> {
public static< T>映射< String,T> createMap(Class< ;? extends Map< String,T>> clazz){
return null;
public static void main(String [] argv){
Map< String,Integer> result = createMap(TreeMap.class);
}
}
但是我得到这个错误,
< T> createMap(java.lang.Class< ;? extends java.util.Map< java.lang.String,T>> )in test.GenericsTest< T>不能应用于(java.lang.Class< java.util.TreeMap>)
如何解决这个问题?
地图< 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));
这将适当地打印出1.该方法的实施很可能是
try
{
return clazz.newInstance();
catch(Exception e)
{
抛出新的RuntimeException(e);
}
更好地实现它们的API会让他们问你类型, T
,并让他们返回他们选择的 Map
,而不是要求你提供所有的细节。否则,只要他们没有用任何数据填充 Map
,就可以通过泛型实例化 Map
自己输入参数如下:
public static< T>映射< String,T> getMap()
{
返回新的TreeMap< String,T>();
}
然后您可以不加警告地访问它:
//注意缺少类型参数,它们被推断
Map< String,Integer> instance = getMap();
//或者,您可以更明确地做到这一点:$ b $ b // Map< String,Integer> instance = ClassName。< Integer> getMap();
他们没有理由要求你为 Class
Map 的类型,除了让你返回一个完全匹配的实现(例如,如果你坚持 HashMap
,那么你将得到一个 HashMap
,如果你坚持一个 TreeMap
,那么你将会得到一个 TreeMap
)。然而,我怀疑 TreeMap
会失去它所构造的任何 Comparator
,并且因为它是不可变的最后
)字段 TreeMap
,那么你不能修复;这意味着 Map
在这种情况下是不一样的,也不可能是您想要的。
如果他们用数据填充 Map
,那么它就更没有意义了。你总是可以传入一个 Map
的实例来填充,或者让它们返回一个 Map
,你可以简单地包装(例如,新的TreeMap< String,Integer>(instance);
),并且他们应该知道哪些 Map
对数据最实用。
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?
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
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:
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.
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.
这篇关于如何在Java中使用泛型类来获得类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!