code: public static Type resolveGenericType(Class<?> type, Type subType) {
      Class<?> rawType;
      if (subType instanceof ParameterizedType)
        rawType = (Class<?>) ((ParameterizedType) subType).getRawType();
      else
        rawType = (Class<?>) subType;
  
      if (type.equals(rawType))
        return subType;
  
      Type result;
      if (type.isInterface()) {
        for (Type superInterface : rawType.getGenericInterfaces())
          if (superInterface != null && !superInterface.equals(Object.class))
            if ((result = resolveGenericType(type, superInterface)) != null)
              return result;
      }
  
      Type superClass = rawType.getGenericSuperclass();
      if (superClass != null && !superClass.equals(Object.class))
        if ((result = resolveGenericType(type, superClass)) != null)
          return result;
  
      return null;
    }
docs: Returns the generic {@code type} using type variable information from the {@code subType} else {@code null} if the
  generic type cannot be resolved.
  
  @param type to resolve generic type for
  @param subType to extract type variable information from
  @return generic {@code type} else {@code null} if it cannot be resolved