为通用超types的types参数创buildTypeToken

我正在为两个依赖的generics模型实现一个Gson TypeAdapter

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

为此,我需要获取TypeTokenTypeAdapter 。 通过做

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

对于任何给定types的AnyType和相关的适配器,我都得到一个types标记。 这就是我需要的ModelA ,但是对于ModelB我需要List<AnyType>的适配器,这是直接使用ModelA<List<AnyType>>的结果。

使用原始types令牌的原始types的接口传递

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

我似乎只得到types擦除types的List

我怎样才能将这两个信息结合起来得到genericsList<AnyType>types或直接创build它? 作为input,它只有ModelB<AnyType>的types标记。

对于给定的行为,我实施了一个简单的testing,显示差异。 我已经从哈恩的答案,使用Gson内部非API类$Gson$Typesexpected部分。

 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(); } } 

Solutions Collecting From Web of "为通用超types的types参数创buildTypeToken"

有一个$Gson$Types ,你可以利用它来检索Type List 。 例如有:

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

将返回TyperawType Type设置为ListtypeArguments的参数[String] 。 因此保留你需要的types。

然后执行这个块

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

会导致CollectionTypeAdaptorFactory适配器与elementTypeAdapter.type设置为类String

如果使用.getType()而不是.getRawType() ,则您正在查找的信息似乎被保留下来:

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

希望你能弄清楚如何从那里创build你的TokenAdaptors