Crear TypeToken para el tipo de argumento de tipo super genérico

Estoy implementando un Gson TypeAdapter para dos modelos genéricos dependend.

 interface ModelA<T> {} interface ModelB<T> extends ModelA<List<T>> {} 

Para esto necesito obtener TypeToken y TypeAdapter . Haciendo

 Type type = ((ParameterizedType) type).getActualTypeArguments()[0]; TypeToken<?> token = TypeToken.get(type); TypeAdapter<?> adapter = gson.getAdapter(token); 

Recibo un token de tipo para ambos modelos de cualquier tipo AnyType y el adaptador de correlación. Esto es lo que necesito para ModelA , pero para ModelB necesitaría el adaptador para List<AnyType> lugar, que es el resultado de usar ModelA<List<AnyType>> directamente.

Utilizar la interfaz del tipo sin formato del token de tipo original pasado

 token.getRawType().getGenericInterfaces()[0] 

Yo sólo parecen obtener el tipo borrado tipo de List .

¿Cómo puedo combinar estas dos informaciones para obtener el tipo genérico List<AnyType> o crearlo directamente? Como entrada sólo tiene el token de tipo para ModelB<AnyType> .

Ejemplo

Para el comportamiento dado implementé una prueba simple mostrando las diferencias. He tomado la parte expected de la respuesta por hahn , utilizando el Gson interno no API clase $Gson$Types .

 public class TypeTokenValidate { public interface ModelA<T> {} public interface ModelB<T> extends ModelA<List<T>> {} @Test public void genericToken() throws Exception { TypeToken<ModelB<String>> token = new TypeToken<ModelB<String>>() {}; ModelB<String> m = new ModelB<String>() {}; Type expected = $Gson$Types.resolve(ModelB.class, m.getClass(), ModelA.class.getTypeParameters()[0]); assertEquals(expected, getActual(token)); } private static Type getActual(TypeToken<?> token) { Type type = token.getType(); //type = token.getRawType().getGenericInterfaces()[0]; type = ((ParameterizedType) type).getActualTypeArguments()[0]; return TypeToken.get(type).getType(); } } 

2 Solutions collect form web for “Crear TypeToken para el tipo de argumento de tipo super genérico”

Hay un $Gson$Types que puede utilizar para recuperar el Type de List de Type . Por ejemplo teniendo:

 ModelB<String> m = new ModelB<String>() {}; Type resolve = $Gson$Types.resolve(m.getClass(), m.getClass(), ModelA.class.getTypeParameters()[0]); 

rawType Type con rawType establecido en List y con typeArguments de [String] . Así preservar los tipos que usted necesita.

Y luego ejecutar este bloque

 TypeToken<?> token = TypeToken.get(resolve); TypeAdapter<?> adapter = gson.getAdapter(token); 

Resultaría con el adaptador de CollectionTypeAdaptorFactory con elementTypeAdapter.type establecido en la clase String .

Si utiliza .getType() lugar de .getRawType() la información que está buscando parece estar preservada:

 import java.util.List; import java.lang.reflect.ParameterizedType; import com.google.gson.reflect.TypeToken; public class Test { public interface ModelA<T> {}; public interface ModelB<T> extends ModelA<List<T>> {} public static void main(String[] args) { // Using java.lang.reflect.*: System.out.println(ModelB.class.getGenericInterfaces()[0]); // out: Test.Test$ModelA<java.util.List<T>> System.out.println(((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0]); // out: java.util.List<T> System.out.println(((ParameterizedType)((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0]).getActualTypeArguments()[0]); // out: T // Recovery from a TokenType instance... // ... using .getRawType() System.out.println(TypeToken.get(ModelB.class.getGenericInterfaces()[0]).getRawType()); // out: interface Test$ModelA System.out.println(TypeToken.get(((ParameterizedType)((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0])).getRawType()); // out: interface java.util.List // ... using .getType() System.out.println(TypeToken.get(ModelB.class.getGenericInterfaces()[0]).getType()); // out: Test$ModelA<java.util.List<T>> System.out.println(TypeToken.get(((ParameterizedType)((ParameterizedType)ModelB.class.getGenericInterfaces()[0]).getActualTypeArguments()[0])).getType()); // out: java.util.List<T> } } 

Esperemos que puedas imaginar cómo crear tus TokenAdaptors desde allí.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.