简体   繁体   English

如何使用Class对象作为参数化类型?

[英]How can I use a Class object as a parameterized type?

So Google turns up a lot of questions about getting the .class of a parameterized type, but I'm trying to go the other way. 因此Google提出了许多有关获取参数化类型的.class的问题,但我正尝试采用另一种方法。

I have a list of Classes, and I need to make a map that uses the Class as a key, and an ArrayList of objects of type Class as the value. 我有一个Classes列表,我需要制作一个使用Class作为键的映射,并使用Class类型的对象的ArrayList作为值。 Something like this: 像这样:

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
}

The problem of course is that it needs a parameterized type, not a class. 当然,问题在于它需要一个参数化类型,而不是一个类。 One possible workaround is to just use map.put(c, new ArrayList<Object>()) , but then I have to know the type and cast every object I pull. 一种可能的解决方法是只使用map.put(c, new ArrayList<Object>()) ,但是随后我必须知道类型并map.put(c, new ArrayList<Object>())我拉出的每个对象。

MyClass myObj = (MyClass) map.get(MyClass.class).get(0);

I also tried making an initialization function like this: 我还尝试过这样的初始化函数:

private <T> ArrayList<T> makeArrayList(Class<T> c) {
    return new ArrayList<T>();
}

This had the syntax that I hoped would work, but it still left me with an ArrayList of Object that had to be cast. 它具有我希望可以使用的语法,但是仍然给我留下了必须转换的Object ArrayList

So is there a way I can just make the ArrayList parameterized with the Class's type? 那么有什么方法可以使ArrayList的类类型成为参数?

Unfortunately, due to the nature of Java's generics (they work by erasure), generics aren't available at runtime. 不幸的是,由于Java泛型的本质(它们通过擦除工作),泛型在运行时不可用。

This means that there is no real way to make map.put(c, new ArrayList<c>()); 这意味着没有真正的方法来制作map.put(c, new ArrayList<c>()); work. 工作。

I recommend doing this instead: Wrap your list in a dedicated object, and give that object the following accessor method: 我建议改为这样做:将列表包装在专用对象中,并为该对象提供以下访问器方法:

public <T> getList(Class<T> key) {
    List<?> list = map.get(key);
    return (List<T>) list;
}

This is going to produce a warning, but as long as the map was constructed properly, you'll be ok. 这将产生警告,但是只要正确构建了地图,您就可以了。

Alternatively, you can do a run time check of all objects to make sure the type match up. 另外,您可以对所有对象进行运行时检查,以确保类型匹配。

public <T> getList(Class<T> key) {
    List<?> list = map.get(key);
    for(Object o : list){
        assert(key.isInstance(o));
    }
    return (List<T>) list;
}

There is absolutely no difference in the compiled bytecode between: 编译后的字节码之间绝对没有区别:

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

The type parameter has no effect on the compiled code; type参数对编译后的代码无效; it only affects the compiler's type-checking. 它仅影响编译器的类型检查。 So, if the type parameter is not available at compile-time, it is useless, as compile-time is the only time where it could be useful. 因此,如果类型参数在编译时不可用,则它是无用的,因为编译时是唯一有用的时间。

You should just write new ArrayList<Object>() or new ArrayList<Integer>() even new ArrayList<CompletelyBogusUnrelatedClass>() ; 您应该只写new ArrayList<Object>()new ArrayList<Integer>()甚至new ArrayList<CompletelyBogusUnrelatedClass>() ; it doesn't matter, because all of them are compatible with ArrayList<?> , which is the value type of your map. 没关系,因为它们都与ArrayList<?>兼容,后者是地图的值类型。

As for your method that creates and returns an ArrayList , it should just be written like this: 至于创建并返回ArrayList ,应该这样编写:

private static <T> ArrayList<T> makeArrayList() {
    return new ArrayList<T>();
}

(That's right, this method returns an ArrayList of whatever element type you want without even knowing what that type is ! This is a clear demonstration that the type parameter is not needed at runtime.) (是的,此方法返回所需的任何元素类型的ArrayList 甚至不知道该类型是什么 !这清楚地证明了在运行时不需要type参数。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果将类用作类型参数,如何在参数化的类中创建此对象的实例? - If I use a class as a type parameter, how can I create an instance of this object within the parameterized class? 如何从另一个类中的public类型的参数化构造函数中调用默认类型的参数化构造函数? - How can I call parameterized constructor of default type from a parameterized constructor of type public which is in another class? 如何从参数化类型方法参数中获取参数化类型类? - How can I get the parameterized-type class from a parameterized-type method argument? 如何使用注释来表示参数化类型? - How can I use annotations to represent a parameterized type? 如何将变量的参数化类型设置为变量所在的类类型? - How do I set a parameterized type of a variable to the type of class the variable is in? 我可以使用 Spring 参数化 class 代替 spring 自动装配吗 - can i use Spring parameterized class used instead of spring autowire 来自类对象的Java参数化类型 - Java Parameterized Type from Class object 如何使用参数化构造函数模拟类的对象? - How do I mock an object of a class with parameterized constructor? 使用匿名类创建参数化类型对象 - Creating parameterized type object using anonymous class 如何在Java中获取参数化类的类对象 - How to obtain a class object of a parameterized class in java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM