Add static factories for array and parameterized type tokens.

These are useful when creating TypeAdapterFactories that delegate to others with more complex types. They also are useful when writing dynamic code that deals with types that cannot be fully reified using the normal subclass technique.
This commit is contained in:
Jake Wharton 2016-08-12 12:11:57 -04:00
parent 8b464231f7
commit 9414b9b3b6
2 changed files with 38 additions and 0 deletions

View File

@ -302,4 +302,19 @@ public class TypeToken<T> {
public static <T> TypeToken<T> get(Class<T> type) {
return new TypeToken<T>(type);
}
/**
* Gets type literal for the parameterized type represented by applying {@code typeArguments} to
* {@code rawType}.
*/
public static TypeToken<?> getParameterized(Type rawType, Type... typeArguments) {
return new TypeToken<Object>($Gson$Types.newParameterizedTypeWithOwner(null, rawType, typeArguments));
}
/**
* Gets type literal for the array type whose elements are all instances of {@code componentType}.
*/
public static TypeToken<?> getArray(Type componentType) {
return new TypeToken<Object>($Gson$Types.arrayOf(componentType));
}
}

View File

@ -19,6 +19,7 @@ package com.google.gson.reflect;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.RandomAccess;
import java.util.Set;
import junit.framework.TestCase;
@ -79,4 +80,26 @@ public final class TypeTokenTest extends TestCase {
// listOfSetOfUnknown = listOfSetOfString; // doesn't compile; must be false
assertFalse(TypeToken.get(b).isAssignableFrom(a));
}
public void testArrayFactory() {
TypeToken<?> expectedStringArray = new TypeToken<String[]>() {};
assertEquals(expectedStringArray, TypeToken.getArray(String.class));
TypeToken<?> expectedListOfStringArray = new TypeToken<List<String>[]>() {};
Type listOfString = new TypeToken<List<String>>() {}.getType();
assertEquals(expectedListOfStringArray, TypeToken.getArray(listOfString));
}
public void testParameterizedFactory() {
TypeToken<?> expectedListOfString = new TypeToken<List<String>>() {};
assertEquals(expectedListOfString, TypeToken.getParameterized(List.class, String.class));
TypeToken<?> expectedMapOfStringToString = new TypeToken<Map<String, String>>() {};
assertEquals(expectedMapOfStringToString, TypeToken.getParameterized(Map.class, String.class, String.class));
TypeToken<?> expectedListOfListOfListOfString = new TypeToken<List<List<List<String>>>>() {};
Type listOfString = TypeToken.getParameterized(List.class, String.class).getType();
Type listOfListOfString = TypeToken.getParameterized(List.class, listOfString).getType();
assertEquals(expectedListOfListOfListOfString, TypeToken.getParameterized(List.class, listOfListOfString));
}
}