Say I have a parent interface/class like so
interface Parent {}
And a number of implementing interfaces that fix the generic type.
I don't think so. Read about type erasure: the generic types are used only for compile-time checking, and then discarded. They're not stored in the compiled class files so they're not available at runtime.
Yes, despite what the others have said, this info is available if you have access to the subclass' Class
object. You need to use getGenericSuperclass
along with getActualTypeArguments
.
ParameterizedType superClass = (ParameterizedType)childClass.getGenericSuperclass();
System.out.println(superClass.getActualTypeArguments()[0]);
In your example, the "actual" type argument should return the Class
for Type
.
If you need to do anything non-trivial with generic types at runtime, consider Guava's TypeToken
. It can answer your question (and many more!) while addressing some of the nuanced concerns raised by commenters:
private interface Parent<T> {}
private interface Intermediate<U, V> extends Parent<V> {}
private interface Child<Z> extends Comparable<Double>, Intermediate<Z, Iterable<String>> {}
public void exploreGuavaTypeTokens() {
final TypeToken<? super Child> token = TypeToken.of(Child.class).getSupertype(Parent.class);
final TypeToken<?> resolved = token.resolveType(Parent.class.getTypeParameters()[0]);
System.out.println(resolved); // "java.lang.Iterable<java.lang.String>"
final Class<?> raw = resolved.getRawType();
System.out.println(raw); // "interface java.lang.Iterable"
}