简体   繁体   English

Java - 创建扩展List的对象

[英]Java - Creating an object extending List

How can I create a list with a specified type argument? 如何创建具有指定类型参数的列表? For example: 例如:

LinkedList<Integer> list = createList(LinkedList.class, Integer.class);

I've tried creating a method for it, but the method doesn't include the type argument when creating the new instance. 我已经尝试为它创建一个方法,但该方法在创建新实例时不包含type参数。

public static <T, L extends List<T>> L createList(Class<L> listClazz, Class<T> valueClazz) throws Exception
{
    return listClazz.getConstructor().newInstance();

    //Instead of
    //  new L<T>();
    //does
    //  new L();
}

I hope my question is clear enough, thank you for any help. 我希望我的问题很清楚,谢谢你的帮助。

You can't do that. 你不能这样做。 Generics have no business at runtime, so you can't create parameterized instance at runtime using reflection. 泛型在运行时没有业务,因此您无法使用反射在运行时创建参数化实例。 At runtime, LinkedList<Intege> is just a LinkedList . 在运行时, LinkedList<Intege>只是一个LinkedList The type information - Integer is erased at compile time through "type erasure". 类型信息 - Integer在编译时通过“类型擦除”被擦除。 The point is, why would you like to do that? 关键是,你为什么要这样做?

 //Instead of // new L<T>(); //does // new L(); 

The two "do" exactly the same thing. 这两个“做”完全相同的事情。 How do you know it "does" one and not the other? 你怎么知道它“做”而不是另一个? Type parameters are compile-time illusions for type-checking. 类型参数是用于类型检查的编译时幻象。 They are not relevant in what the code "does". 它们与代码“做”无关。 To create an instance of LinkedList<T> , you do not need to know what T is, because it doesn't really exist after type erasure. 要创建LinkedList<T>的实例,您不需要知道T是什么,因为它在类型擦除后并不存在。

I think the issue you are having has nothing to do with the code inside the function, but with the signature of the method. 我认为你遇到的问题与函数内部的代码无关,而是与方法的签名有关。 By the very fact that the method is declared as it is, and you are passing an expression of type Class<LinkedList> (the type of LinkedList.class ) to it, L must be LinkedList , and since the method returns L , the compiler must consider its return to by type LinkedList . 通过这一事实,该方法被声明为是,和要传递类型的表达式Class<LinkedList> (类型LinkedList.class )给它, L必须是LinkedList ,并且由于该方法返回L ,编译器必须考虑通过LinkedList类型返回它。 None of this has anything to do with the code inside the method. 这些都与方法内的代码无关。

If you want the method's return type to be considered as LinkedList<Integer> , then just pass in an expression of type Class<LinkedList<Integer>> . 如果希望将方法的返回类型视为LinkedList<Integer> ,则只需传入Class<LinkedList<Integer>>类型的表达式。 Simple, right? 简单吧? How do you get an expression of type Class<LinkedList<Integer>> ? 如何获得Class<LinkedList<Integer>>类型的表达式? For one, you could do (Class<LinkedList<Integer>>)(Class<?>)LinkedList.class . 首先,你可以做(Class<LinkedList<Integer>>)(Class<?>)LinkedList.class

If that seems kind of bogus, it's because Class is fundamentally a runtime thing -- it allows runtime creation of an object from that class. 如果这看起来有点虚假,那是因为Class基本上是一个运行时的东西 - 它允许运行时从该类创建一个对象。 Using it with Generics, a compile-time type-checking mechanism, is fundamentally flawed. 将它与Generics(编译时类型检查机制)一起使用从根本上是有缺陷的。 There is just one class object in existence for any class, eg LinkedList . 任何类都只有一个类对象,例如LinkedList Is it LinkedList or LinkedList<Integer> or LinkedList<String> ? LinkedList还是LinkedList<Integer>LinkedList<String> Well, it could be all of these, in the sense the the newInstance() method could create any of them (there is no difference at runtime). 好吧,它可能就是所有这些,在某种意义上, newInstance()方法可以创建它们中的任何一个(在运行时没有区别)。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM