Types { public static Class<?> getActualTypeArgument(Class<?> declaringClass, Type genericType) { if(null == declaringClass) { return getActualTypeArgument(genericType); }else{ return getActualType(declaringClass, getTypeArgument(genericType)); } } protected  Types(); static TypeInfo getTypeInfo(Class<?> type); static TypeInfo getTypeInfo(Class<?> type,Type genericType); static boolean isSimpleType(Class<?> type,Type genericType); static boolean isCollectionType(Class<?> type, Type genericType); static Class<?> getElementType(Class<?> type, Type genericType); static Type getTypeArgument(Type genericType); static Type[] getTypeArguments(Type genericType); static Class<?> getActualTypeArgument(Class<?> declaringClass, Type genericType); static Class<?> getActualType(Class<?> declaringClass, Type type); static Class<?> getActualTypeArgument(Type genericType); static Class<?>[] getActualTypeArguments(Type genericType); static Class<?> getActualType(Type type); static Class<?>[] getActualTypes(Type[] types); static boolean isAssignable(Type type, Type toType); static Map<TypeVariable<?>, Type> determineTypeArguments(Class<?> cls, ParameterizedType superType);  }
@Test public void testGenericTypeLost() throws Exception { Method list = SubSub.class.getMethod("list"); assertEquals(String.class, Types.getActualTypeArgument(SubSub.class, list.getGenericReturnType())); }