如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 05:32:41  来源:igfitidea点击:

How to get class with generics types in Java

javagenerics

提问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 Mapof their choosing instead of asking you for all of the details. Otherwise, as long as they are not filling in the Mapwith any data, you can instantiate a Mapwith 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 Classtype of your Mapexcept 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 TreeMapwill lose any Comparatorthat it was constructed with, and since that is an immutable (final) field of TreeMap, then you cannot fix that; that means that the Mapis 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 Mapwith data, then it makes even less sense. You could always pass in an instance of a Mapto fill, or have them return a Mapthat you can simply wrap (e.g., new TreeMap<String, Integer>(instance);), and they should know which Mapoffers the most utility to the data.

如果他们正在填写Map数据,那么就更没有意义了。你总是可以传入一个 a 的实例Map来填充,或者让他们返回一个Map你可以简单地包装的(例如,new TreeMap<String, Integer>(instance);),他们应该知道哪个Map为数据提供了最多的效用。