### Question:
ReflectionUtils { public static <T> List<Class<?>> getTypeArguments(Class<T> baseClass, Class<? extends T> childClass) { Preconditions.checkArgument(!baseClass.isInterface(), "baseClass should not be an interface"); Preconditions.checkArgument(baseClass.isAssignableFrom(childClass), "childClass should be a sub class of baseClass"); Map<Type, Type> resolvedTypes = new HashMap<Type, Type>(); Type type = childClass; while (!getClass(type).equals(baseClass)) { if (type instanceof Class) { type = ((Class<?>) type).getGenericSuperclass(); } else { ParameterizedType parameterizedType = (ParameterizedType) type; Class<?> rawType = (Class<?>) parameterizedType.getRawType(); Type[] actualTypeArguments = parameterizedType .getActualTypeArguments(); TypeVariable<?>[] typeParameters = rawType.getTypeParameters(); for (int i = 0; i < actualTypeArguments.length; i++) { resolvedTypes .put(typeParameters[i], actualTypeArguments[i]); } if (!rawType.equals(baseClass)) { type = rawType.getGenericSuperclass(); } } } Type[] actualTypeArguments; if (type instanceof Class) { actualTypeArguments = ((Class<?>) type).getTypeParameters(); } else { actualTypeArguments = ((ParameterizedType) type) .getActualTypeArguments(); } List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>(); for (Type baseType : actualTypeArguments) { while (resolvedTypes.containsKey(baseType)) { baseType = resolvedTypes.get(baseType); } typeArgumentsAsClasses.add(getClass(baseType)); } return typeArgumentsAsClasses; }  static List<Class<?>> getTypeArguments(Class<T> baseClass, Class<? extends T> childClass); static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes); static Field findField(Class<?> clazz, String fieldName); static List<Field> findFields(Class<?> clazz); static Method getMethod(Class<?> clazz, String methodName, Class<?>...paramTypes); static Object invokeStaticMethod(Class<?> clazz, String methodName, Object...params); static Object invokeMethod(Object object, String methodName, Object...params); static T instantiateClass(Class<T> clazz, Object... params); @SuppressWarnings("unchecked") static Constructor<T> findConstructor(Class<T> clazz, Class<?>... expectedParamTypes); static Class<?> getCollectionElementType(Type type); static Class<?> getMapKeyType(Type type); static Class<?> getMapValueType(Type type);  }### Answer:
@Test public void shouldResolveTypeArg() { List<?> typeArguments = ReflectionUtils.getTypeArguments(SuperClass.class, SubClass1.class); assertSame(String.class, typeArguments.get(0)); assertSame(Integer.class, typeArguments.get(1)); typeArguments = ReflectionUtils.getTypeArguments(SuperClass.class, SubClass2.class); assertSame(String.class, typeArguments.get(0)); typeArguments = ReflectionUtils.getTypeArguments(SuperClass.class, SubClass3.class); assertSame(String.class, typeArguments.get(0)); assertSame(Integer.class, typeArguments.get(1)); typeArguments = ReflectionUtils.getTypeArguments(SubClass2.class, SubClass3.class); assertSame(Integer.class, typeArguments.get(0)); }