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;
  }
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.