我正在实现一个 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 传递的原始类型的接口(interface)
token.getRawType().getGenericInterfaces()[0]
我似乎只得到 List
的删除类型.
我如何结合这两个信息来获得通用的 List<AnyType>
输入还是直接创建?作为输入,它只有 ModelB<AnyType>
的类型标记.
例子
对于给定的行为,我实现了一个简单的测试来显示差异。我拿了expected
hahn 的答案的一部分,使用 Gson 内部非 API 类 $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();
}
}
最佳答案
有一个$Gson$Types
,您可以利用它来检索类型List
的Type
。例如有:
ModelB<String> m = new ModelB<String>() {};
Type resolve = $Gson$Types.resolve(m.getClass(), m.getClass(), ModelA.class.getTypeParameters()[0]);
将返回 Type
,其中 rawType
设置为 List
并且 typeArguments
为 [String]
。从而根据需要保留类型。
然后执行这个 block
TypeToken<?> token = TypeToken.get(resolve);
TypeAdapter<?> adapter = gson.getAdapter(token);
将导致 CollectionTypeAdaptorFactory
的适配器将 elementTypeAdapter.type
设置为类 String
。
关于java - 为泛型父类(super class)型的类型参数创建 TypeToken,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39142029/