Reputation: 27286
The following code:
public static void main(String args[]) throws NoSuchFieldException {
List<Integer> li = new ArrayList<Integer>();
ParameterizedType apType = (ParameterizedType) li.getClass().getGenericSuperclass();
Type[] typeArguments = apType.getActualTypeArguments();
int _i = 0;
for (Type type : typeArguments) {
System.out.format("parameterized type %d is: %s", ++_i, type);
}
}
produces:
parameterized type 1 is: E
Also, it's not clear to me why I can cast the superclass to ParameterizedType but not the class itself. Trying to cast the result of li.getClass() as a ParameterizedType yields the following compile time error:
required: ParameterizedType found: Class where CAP#1 is a fresh type-variable: CAP#1 extends List from capture of ? extends List
I've seen this relevant SO post but it hasn't enlightened me.
Upvotes: 1
Views: 215
Reputation: 70564
All instances of a generic class share the same runtime class:
new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass()
Put differently, the runtime does not track the actual type arguments used to instantiate a generic class. However, it does know the types declared in the source code, and that's what getGenericSuperclass() and friends return. So if you have a class:
class Environment extends HashMap<String, Object> {
}
The expression
new Environment().getClass().getGenericSuperclass()
returns
java.util.HashMap<java.lang.String, java.lang.Object>
In contrast, if you declare
class Environment<E> extends HashMap<String, E> {
}
the same expression returns
java.util.HashMap<java.lang.String, E>
So yes, getGenericSuperclass returns the actual type parameters as declared in the source code, but those type parameters may contain type variables declared elsewhere.
Also, it's not clear to me why I can cast the superclass to ParameterizedType but not the class itself.
A ParametrizedType
object represents a compile time type with a non-empty list of type arguments, a Class
object a runtime type (which doesn't have any type arguments). Therefore, a Class
is not a ParametrizedType
.
Upvotes: 4