guava/src/com/google/common/reflect/TypeToken.java
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;
  }
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;
  }
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 ; }
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.
Returns subtype of {