栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用GSON反序列化嵌套的通用类时的奇怪行为

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用GSON反序列化嵌套的通用类时的奇怪行为

简短的答案是,您需要移动

TypeToken
out 的创建,在创建标记()时
Executor
T
in
绑定,然后将类型标记传递给构造函数。
Response<T>``new TypeToken<Response<Language>>(){}``Executor

长答案是:

类型上的泛型通常在运行时删除,除非使用泛型参数绑定 编译 类型。在这种情况下,编译器会将泛型类型信息插入已编译的类中。在其他情况下,这是不可能的。

因此,例如,请考虑:

List<Integer> foo = new ArrayList<Integer>();class IntegerList extends ArrayList<Integer> { ... }List<Integer> bar = new IntegerList();

在运行时,Java 知道

bar
包含整数,因为
Integer
类型是
ArrayList
在编译时绑定的,因此泛型类型信息保存在
IntegerList
类文件中。但是,的通用类型信息
foo
已删除,因此在运行时实际上不可能确定
foo
应该包含
Integer

因此经常会出现这样的情况,即在正常情况下会在运行时将其擦除的情况下,例如在GSON中解析JSON数据的情况下,我们需要通用类型信息。在这些情况下,我们可以利用这样的事实,即类型信息在编译时

IntegerList
通过使用类型标记(在上面的示例中)进行绑定而得以保留,而这些标记实际上只是可以方便地存储泛型类型信息的微小匿名类。

现在到您的代码:

Type responseType = new TypeToken<Response<T>>() {}.getType();

在您的

Executor
类的这一行中,我们创建一个匿名类(从继承
TypeToken
),其类型
Response<T>
在编译时进行了硬编码(绑定)。因此,在运行时,GSON能够确定您需要的对象
Response<T>
。但是它不知道是什么
T
,因为您没有在编译时指定它!因此,GSON无法确定它创建
List
Response
对象的类型是什么,而只是创建了一个
StringMap

这个故事的寓意是您需要

T
在编译时指定它。如果
Executor
要一般使用,则可能需要在客户端代码中在该类之外创建类型标记。就像是:

class Executor<T> {    private TypeToken<Response<T>> responseType;    private Response<T> response;    public Executor(TypeToken<Response<T>> responseType) {        this.responseType = responseType;    }    public void execute() {        this.response = new Gson().fromJson(json, responseType.getType());    }    public Response<T> getResponse() { return this.response; }}// client pre:Executor<Language> executor = new Executor<Language>(new TypeToken<Response<Language>>() { });executor.execute();List<Language> languages = executor.getResponse().getData();System.out.println(languages.get(0).alias); // prints "be"

顺便说一句,我确实在我的机器上测试了以上内容。

抱歉,时间太长!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/376117.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号