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.
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
. The type information - Integer
is erased at compile time through "type erasure". 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.
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
. 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>>
. Simple, right? How do you get an expression of type Class<LinkedList<Integer>>
? For one, you could do (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. Using it with Generics, a compile-time type-checking mechanism, is fundamentally flawed. There is just one class object in existence for any class, e.g. LinkedList
. Is it LinkedList
or LinkedList<Integer>
or 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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With