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.
(Class<?> subclass)
| 428 | * returned. |
| 429 | */ |
| 430 | public final TypeToken<? extends T> getSubtype(Class<?> subclass) { |
| 431 | checkArgument( |
| 432 | !(runtimeType instanceof TypeVariable), "Cannot get subtype of type variable <%s>", this); |
| 433 | if (runtimeType instanceof WildcardType) { |
| 434 | return getSubtypeFromLowerBounds(subclass, ((WildcardType) runtimeType).getLowerBounds()); |
| 435 | } |
| 436 | // unwrap array type if necessary |
| 437 | if (isArray()) { |
| 438 | return getArraySubtype(subclass); |
| 439 | } |
| 440 | // At this point, it's either a raw class or parameterized type. |
| 441 | checkArgument( |
| 442 | getRawType().isAssignableFrom(subclass), "%s isn't a subclass of %s", subclass, this); |
| 443 | Type resolvedTypeArgs = resolveTypeArgsForSubclass(subclass); |
| 444 | @SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above |
| 445 | TypeToken<? extends T> subtype = (TypeToken<? extends T>) of(resolvedTypeArgs); |
| 446 | checkArgument( |
| 447 | subtype.isSubtypeOf(this), "%s does not appear to be a subtype of %s", subtype, this); |
| 448 | return subtype; |
| 449 | } |
| 450 | |
| 451 | /** |
| 452 | * Returns true if this type is a supertype of the given {@code type}. "Supertype" is defined |