Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将类对象用作参数化类型?_Java_Generics - Fatal编程技术网

Java 如何将类对象用作参数化类型?

Java 如何将类对象用作参数化类型?,java,generics,Java,Generics,因此,谷歌提出了很多关于获取参数化类型的.class的问题,但我正试图走另一条路 我有一个类列表,我需要制作一个映射,使用Class作为键,使用Class类型的对象的ArrayList作为值。大概是这样的: Class[] classes = getArrayOfClasses(); HashMap<Class, ArrayList<?>> map = new HashMap<Class, ArrayList<?>>(); for(Class c

因此,谷歌提出了很多关于获取参数化类型的
.class
的问题,但我正试图走另一条路

我有一个类列表,我需要制作一个映射,使用
Class
作为键,使用Class类型的对象的
ArrayList
作为值。大概是这样的:

Class[] classes = getArrayOfClasses();
HashMap<Class, ArrayList<?>> map = new HashMap<Class, ArrayList<?>>();
for(Class c : classes) {
    map.put(c, new ArrayList<c>());    // here is where the problem is
}
private <T> ArrayList<T> makeArrayList(Class<T> c) {
    return new ArrayList<T>();
}
private static <T> ArrayList<T> makeArrayList() {
    return new ArrayList<T>();
}
我还尝试过创建如下初始化函数:

Class[] classes = getArrayOfClasses();
HashMap<Class, ArrayList<?>> map = new HashMap<Class, ArrayList<?>>();
for(Class c : classes) {
    map.put(c, new ArrayList<c>());    // here is where the problem is
}
private <T> ArrayList<T> makeArrayList(Class<T> c) {
    return new ArrayList<T>();
}
private static <T> ArrayList<T> makeArrayList() {
    return new ArrayList<T>();
}
private ArrayList makeArrayList(c类){
返回新的ArrayList();
}
这是我希望可以使用的语法,但它仍然给我留下了一个
Object
ArrayList
,必须强制转换


那么有没有一种方法可以让
ArrayList
用类的类型参数化呢?

不幸的是,由于Java泛型的性质(它们通过擦除工作),泛型在运行时不可用

这意味着没有真正的方法来生成
map.put(c,newarraylist())工作

我建议改为这样做:将列表包装在专用对象中,并为该对象提供以下访问器方法:

public <T> getList(Class<T> key) {
    List<?> list = map.get(key);
    return (List<T>) list;
}
public getList(类键){
List=map.get(键);
返回(列表)列表;
}
这将产生一个警告,但只要地图构造正确,您就可以了

或者,您可以对所有对象执行运行时检查,以确保类型匹配

public <T> getList(Class<T> key) {
    List<?> list = map.get(key);
    for(Object o : list){
        assert(key.isInstance(o));
    }
    return (List<T>) list;
}
public getList(类键){
List=map.get(键);
用于(对象o:列表){
断言(key.isInstance(o));
}
返回(列表)列表;
}

编译后的字节码在以下两种情况下完全没有区别:

new ArrayList();
new ArrayList<T>();
new ArrayList<String>();
new ArrayList<Integer>();

(没错,此方法返回您想要的任何元素类型的
ArrayList
,甚至不知道该类型是什么!这清楚地证明了在运行时不需要类型参数。)

使用泛型方法:
List getList(类类型)
。由于类型是一个类,我希望有某种方法可以绕过类型擦除,但我想不是。在函数中封装强制转换并抑制警告可能是最好的解决方法。谢谢