Support non-generic type for `TypeToken.getParameterized` for legacy reasons (#2447)
This partially restores the behavior before a589ef2008
,
except that back then for a non-generic type a bogus `TypeToken(ParameterizedType)`
was created, whereas now a `TypeToken(Class)` is created instead.
This commit is contained in:
parent
79ae239a49
commit
a38b757bc4
|
@ -337,9 +337,12 @@ public class TypeToken<T> {
|
|||
* As seen here the result is a {@code TypeToken<?>}; this method cannot provide any type safety,
|
||||
* and care must be taken to pass in the correct number of type arguments.
|
||||
*
|
||||
* <p>If {@code rawType} is a non-generic class and no type arguments are provided, this method
|
||||
* simply delegates to {@link #get(Class)} and creates a {@code TypeToken(Class)}.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If {@code rawType} is not of type {@code Class}, if it is not a generic type, or if the
|
||||
* type arguments are invalid for the raw type
|
||||
* If {@code rawType} is not of type {@code Class}, or if the type arguments are invalid for
|
||||
* the raw type
|
||||
*/
|
||||
public static TypeToken<?> getParameterized(Type rawType, Type... typeArguments) {
|
||||
Objects.requireNonNull(rawType);
|
||||
|
@ -354,10 +357,16 @@ public class TypeToken<T> {
|
|||
Class<?> rawClass = (Class<?>) rawType;
|
||||
TypeVariable<?>[] typeVariables = rawClass.getTypeParameters();
|
||||
|
||||
// Note: Does not check if owner type of rawType is generic because this factory method
|
||||
// does not support specifying owner type
|
||||
if (typeVariables.length == 0) {
|
||||
throw new IllegalArgumentException(rawClass.getName() + " is not a generic type");
|
||||
int expectedArgsCount = typeVariables.length;
|
||||
int actualArgsCount = typeArguments.length;
|
||||
if (actualArgsCount != expectedArgsCount) {
|
||||
throw new IllegalArgumentException(rawClass.getName() + " requires " + expectedArgsCount +
|
||||
" type arguments, but got " + actualArgsCount);
|
||||
}
|
||||
|
||||
// For legacy reasons create a TypeToken(Class) if the type is not generic
|
||||
if (typeArguments.length == 0) {
|
||||
return get(rawClass);
|
||||
}
|
||||
|
||||
// Check for this here to avoid misleading exception thrown by ParameterizedTypeImpl
|
||||
|
@ -366,13 +375,6 @@ public class TypeToken<T> {
|
|||
+ " it requires specifying an owner type");
|
||||
}
|
||||
|
||||
int expectedArgsCount = typeVariables.length;
|
||||
int actualArgsCount = typeArguments.length;
|
||||
if (actualArgsCount != expectedArgsCount) {
|
||||
throw new IllegalArgumentException(rawClass.getName() + " requires " + expectedArgsCount +
|
||||
" type arguments, but got " + actualArgsCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < expectedArgsCount; i++) {
|
||||
Type typeArgument = Objects.requireNonNull(typeArguments[i], "Type argument must not be null");
|
||||
Class<?> rawTypeArgument = $Gson$Types.getRawType(typeArgument);
|
||||
|
|
|
@ -146,6 +146,9 @@ public final class TypeTokenTest {
|
|||
class LocalGenericClass<T> {}
|
||||
TypeToken<?> expectedLocalType = new TypeToken<LocalGenericClass<Integer>>() {};
|
||||
assertThat(TypeToken.getParameterized(LocalGenericClass.class, Integer.class)).isEqualTo(expectedLocalType);
|
||||
|
||||
// For legacy reasons, if requesting parameterized type for non-generic class, create a `TypeToken(Class)`
|
||||
assertThat(TypeToken.getParameterized(String.class)).isEqualTo(TypeToken.get(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -158,7 +161,7 @@ public final class TypeTokenTest {
|
|||
assertThat(e).hasMessageThat().isEqualTo("rawType must be of type Class, but was java.lang.String[]");
|
||||
|
||||
e = assertThrows(IllegalArgumentException.class, () -> TypeToken.getParameterized(String.class, Number.class));
|
||||
assertThat(e).hasMessageThat().isEqualTo("java.lang.String is not a generic type");
|
||||
assertThat(e).hasMessageThat().isEqualTo("java.lang.String requires 0 type arguments, but got 1");
|
||||
|
||||
e = assertThrows(IllegalArgumentException.class, () -> TypeToken.getParameterized(List.class, new Type[0]));
|
||||
assertThat(e).hasMessageThat().isEqualTo("java.util.List requires 1 type arguments, but got 0");
|
||||
|
|
Loading…
Reference in New Issue