Determine generic arguments of List<>
I'm using reflection to walk the field members of a class and I need to know 开发者_StackOverflow中文版for List<> subclasses, what the generic type parameters are.
Given a field that has a type that is a subclass of List, how can I tell in a generic way what the type parameters of List<> are?
For example:
class X<T> {
List<String> x1; // String
ArrayList<String> x2; // String
SubclassOfArrayListString x3; // String
List<?> x4; // error
List<T> x5; // error
}
class SubclassOfArrayListString extends ArrayList<String> {
// ...
}
NOTE: I added <T>
to X above to illustrate that there might be cases where there isn't a correct answer - it has nothing to do with the problem, except being something to consider when answering.
You can't because generic type information is lost on compilation (*). That's also the reason you cannot create an array of some generic type T
at runtime.
At runtime, every List<T>
is again a raw type List
-- you could even add an Integer
to something declared as List<String>
, generics won't and can't prevent that [Edit: using unchecked casts or a widening cast to a raw type; this will result in (suppressable) compiler warnings but no errors].
(*) Edit: I learned some new and stand corrected, certain type parameters (implementors of GenericDeclaration like Class
, Constructor
, Field
and the return, parameter and exception types of Method
) will be retained in the byte code and can be accessed at runtime using Field.getGenericType() and similar accessors.
public class X<T extends List> {
T field;
}
Is that what you need?
Read this tutorial about Generics : Generics Tutorial. This should clear things up.
This pdf has also good examples at the end of the wildcard usage as well as the extends ans super keywords. PDF Doc
Basically, Use Container<? extends A>
when you want to read from the container
Use Container<? super A>
when you want to write to the container.
精彩评论