java - 为泛型父类(super class)型的类型参数创建 TypeToken

标签 java android generics gson typetoken

我正在实现一个 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);

我得到了任何给定类型的两个模型的类型标记 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,您可以利用它来检索类型ListType。例如有:

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/

相关文章:

android - 不允许明文 http 流量

generics - 在 Scala 中模拟可变参数模板

generics - f# 可区分联合泛型

java - 从图库中选择一张图片并将其显示在另一个 Activity 中

java - 不支持的类版本错误

从 textview 分享文本的 Android 按钮

Android Paging 3 库 : how to change list with new param?

java - 不兼容的类型 : T#1 cannot be converted to T#2

java - 在 JSP 中格式化 HTML

java - 输入扫描仪被跳过