I am trying to get the Class<?>
for the generic type used by an interface at run time.
So if I have the following
public class A<T> implements B<Z> {}
public interface B<T> extends C<Z> {}
public interface C<T> {}
public class Z {}
A temp = new A<MyClass>();
I want to be able to get the Class<?>
of the first (or later) generic of B, C, or D, given the instance temp
.
Right now I have this, but it only works for interfaces this instance's class directly implements. I want to modify it to work regardless of how this instance inherited the target interface.
/**
* Finds this instances implementation of the interfaceClass, and returns
* the associated generic type
*
* @param instance
* the instance to extract from
* @param interfaceClass
* The class this instance implements
* @param paramIndex
* Index of the generic class to get the class of
* @return The class of the generic type
* @throws ClassNotFoundException
*/
public static <T> Class<?> ParameterizedClass(final T instance, final Class<T> interfaceClass, final int paramIndex)
throws ClassNotFoundException {
final Type[] sooper = instance.getClass().getGenericInterfaces();
for (final Type t : sooper) {
if (!(t instanceof ParameterizedType)) {
continue;
}
final ParameterizedType type = ((ParameterizedType) t);
if (type.getRawType().getTypeName().equals(interfaceClass.getTypeName())) {
return Class.forName(type.getActualTypeArguments()[paramIndex].getTypeName());
}
}
return null;
}
With the code I have now, and the example classes, I get the following results
ParameterizedClass(new A<Integer>, B.class, 0); // returns Class<Z>
ParameterizedClass(new A<Integer>, C.class, 0); // returns null, but I want Class<Z>
This is what I mean by directly implements. I can't find how to read the inherited classes.