【发布时间】:2016-08-25 09:53:11
【问题描述】:
我正在为两个依赖泛型模型实现 Gson TypeAdapter。
interface ModelA<T> {}
interface ModelB<T> extends ModelA<List<T>> {}
为此,我需要获取TypeToken 和TypeAdapter。通过做
Type type = ((ParameterizedType) type).getActualTypeArguments()[0];
TypeToken<?> token = TypeToken.get(type);
TypeAdapter<?> adapter = gson.getAdapter(token);
我得到了任何给定类型AnyType 和相关适配器的类型标记。这是我对ModelA 所需要的,但对于ModelB,我需要List<AnyType> 的适配器,这是直接使用ModelA<List<AnyType>> 的结果。
使用原始类型令牌传递的原始类型的接口
token.getRawType().getGenericInterfaces()[0]
我似乎只得到List的类型擦除类型。
如何结合这两个信息来获得通用的List<AnyType> 类型或直接创建它?作为输入,它只有ModelB<AnyType> 的类型标记。
示例
对于给定的行为,我实施了一个简单的测试来显示差异。我使用 Gson 内部非 API 类 $Gson$Types,从 hahn 的答案中提取了 expected 部分。
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();
}
}
【问题讨论】:
-
您的意思是
token.getRawType().getGenericInterfaces()[0]不能转换为ParametrizedType?如果是,您只需递归地继续。 -
是的,但
getActualTypeArguments()[0]似乎没有泛型类型信息。因此我只得到List,没有任何关于T的信息 -
我们知道
java.util.List有一个类型参数,所以如果你直接使用反射到 List.class 那么信息应该在那里,对吧? -
反射不提供任何关于泛型的信息。我认为这是原始类型的问题,因为它是
Class<?>类型,因此会在运行时擦除泛型类型。 -
对于 ModelB 或 ModelA,你会得到什么合适的 ````type```?那不是 ModelB.class.getTypeParameters() 吗?您可以将其添加到您的问题代码中吗? List.class.getTypeParameters() 给你什么?
标签: java android generics gson typetoken