首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gson的RuntimeTypeAdapterFactory没有序列化类型

Gson的RuntimeTypeAdapterFactory没有序列化类型
EN

Stack Overflow用户
提问于 2018-12-07 08:03:20
回答 2查看 913关注 0票数 1

多年来,我一直很高兴地使用gson,需要序列化和反序列化一些多态类型,并遇到了这个额外的gson类型,这似乎正是我所需要的:

https://github.com/google/gson/blob/master/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java

但是,不管我尝试了什么,它都不是序列化类型字段,所以当它试图反序列化时,自然会出现以下错误:

不能反序列化类<...>,因为它没有定义名为type的字段

即使使用文件中的演示代码对我也不起作用:

代码语言:javascript
复制
class Shape {
  int x;
  int y;
}

class Diamond extends Shape {
  int width;
  int height;
}

...

Gson g = (new GsonBuilder()).registerTypeAdapterFactory(
    RuntimeTypeAdapterFactory
        .of(Shape.class)
        .registerSubtype(Diamond.class)
).create();

Diamond d = new Diamond();
d.x = 10;
d.y = 20;
d.width = 25;
d.height = 35;

String json = g.toJson(d);

它产生:

{“宽度”:25,“高度”:35,"x":10,"y":20}

注意,我尝试为of()和寄存器()指定自定义字符串,将类型添加到toJson()调用中,甚至将对象嵌入到外部集合中,但这并没有什么区别。

实际上,标准的Gson对象和这个用构建器和类型工厂创建的对象之间的输出没有区别。

我注意到,如果我调试代码并在RuntimeTypeAdapterFactory读和写方法中设置断点,它将命中read() (然后进入上面的失败),但它从未命中写方法。只是完全跳过了。

这里发生什么事情?我使用的代码都是来自上述链接的所有最新的和直接的代码(截止到今天)。

EN

回答 2

Stack Overflow用户

发布于 2018-12-07 17:43:52

感谢来自公共存储库的贡献者的帮助,问题是包含基本类型所需的序列化步骤。因此,与其简单地:

代码语言:javascript
复制
g.toJson(d);

它必须是:

代码语言:javascript
复制
g.toJson(d, Shape.class);

我试过g.toJson(d, Diamond.class),但这对输出没有任何影响。希望这能帮到别人!

票数 3
EN

Stack Overflow用户

发布于 2019-03-05 10:50:38

来自rjcarr的解决方案(在调用toJson中包括类对象)并不实用,因为您通常将多态对象作为其他对象的成员或列表中的元素。

事实上,RuntimeTypeAdapterFactory中有一个bug。在这个github哨所中,用户ultraon提出了一种对我有用的解决方案:

替换

代码语言:javascript
复制
if (type.getRawType() != baseType)

使用

代码语言:javascript
复制
if (null == type || !baseType.isAssignableFrom(type.getRawType()))

在第185行,方法create的类RuntimeTypeAdapterFactory

现在,类型属性包含在JSON中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53665467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档