sblundy
sblundy

Reputation: 61414

Getting generic parameter from supertype class

Say I have a parent interface/class like so

interface Parent<T> {}

And a number of implementing interfaces that fix the generic type.

interface Child extends Parent<Type> {}

Can I use reflection to get the instance of Class representing T if I have the Class object for Child. Something like this:

<T, I extends Parent<T>> I create(Class<I> type) {
    Class<T> tType = ...
    ...
}

Currently I'm having tType be passed in as a parameter, but I'd like to simplify things if I can.

Upvotes: 6

Views: 4670

Answers (3)

Woody Zenfell III
Woody Zenfell III

Reputation: 1955

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"
}

Upvotes: 4

Kirk Woll
Kirk Woll

Reputation: 77546

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.

Upvotes: 11

Wyzard
Wyzard

Reputation: 34563

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.

Upvotes: -3

Related Questions