Background
My understanding of Java generics is it being completely a compile time feature (mainly focusing on type safety checks)
If a class extends a generic class or interface and provides a concrete type for the parameter, then that type is available via Class.getGenericSuperclass(). That method will (in this case) return a ParameterizedType that will contain the actual parameterization.
For instance, if you have:
class BigIntegerList extends ArrayList {}
Then you can do:
Class fooClass = BigIntegerList.class;
Type superclass = fooClass.getGenericSuperclass();
if (superclass instanceof ParameterizedType) {
ParameterizedType parameterized = (ParameterizedType) superclass;
Type[] parameterizations = parameterized.getActualTypeArguments();
System.out.println(Arrays.toString(parameterizations));
// prints: "[class java.math.BigInteger]"
}
This is indeed used by reflection-heavy libraries such as Guice. Another example is Jackson's TypeReference, which can let you read a JSON list-of-things as list-of-BigDecimal (for instance).