code: public static Type getSuperType(Type type) {
          if (type instanceof ParameterizedType) {
              ParameterizedType parameterizedType = (ParameterizedType) type;
              Type genericSuperClass = ((Class<?>) parameterizedType.getRawType()).getGenericSuperclass();
              if (genericSuperClass instanceof ParameterizedType) {
                  /*
                   * Find erased generic types for the super class and replace
                   * with actual type arguments from the parameterized type
                   */
                  Type[] superTypeArguments = getTypeArguments(genericSuperClass);
                  List<Type> typeParameters = Arrays.asList(((Class<?>) parameterizedType.getRawType()).getTypeParameters());
                  int j = 0;
                  for (int i = 0; i != superTypeArguments.length; i++) {
                      if (typeParameters.contains(superTypeArguments[i])) {
                          superTypeArguments[i] = parameterizedType.getActualTypeArguments()[j++];
                      }
                  }
                  return new ParameterizedType() {
                      @Override
                      public Type[] getActualTypeArguments() {
                          return superTypeArguments;
                      }
  
                      @Override
                      public Type getRawType() {
                          return ((ParameterizedType) genericSuperClass).getRawType();
                      }
  
                      @Override
                      public Type getOwnerType() {
                          return null;
                      }
                  };
              } else {
                  return genericSuperClass;
              }
          } else {
              return ((Class<?>) type).getGenericSuperclass();
          }
      }
docs: Get the super type for a given type.
  
  @param type the input type
  @return the direct super type