code: public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
      checkArgument(
          !(runtimeType instanceof TypeVariable), "Cannot get subtype of type variable <%s>", this);
      if (runtimeType instanceof WildcardType) {
        return getSubtypeFromLowerBounds(subclass, ((WildcardType) runtimeType).getLowerBounds());
      }
      // unwrap array type if necessary
      if (isArray()) {
        return getArraySubtype(subclass);
      }
      // At this point, it's either a raw class or parameterized type.
      checkArgument(
          getRawType().isAssignableFrom(subclass), "%s isn't a subclass of %s", subclass, this);
      Type resolvedTypeArgs = resolveTypeArgsForSubclass(subclass);
      @SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above
      TypeToken<? extends T> subtype = (TypeToken<? extends T>) of(resolvedTypeArgs);
      checkArgument(
          subtype.isSubtypeOf(this), "%s does not appear to be a subtype of %s", subtype, this);
      return subtype;
    }
docs: Returns subtype of {@code this} with {@code subclass} as the raw class. For example, if this is
  {@code Iterable<String>} and {@code subclass} is {@code List}, {@code List<String>} is
  returned.