多年来,我一直很高兴地使用gson,需要序列化和反序列化一些多态类型,并遇到了这个额外的gson类型,这似乎正是我所需要的:
但是,不管我尝试了什么,它都不是序列化类型字段,所以当它试图反序列化时,自然会出现以下错误:
不能反序列化类<...>,因为它没有定义名为type的字段
即使使用文件中的演示代码对我也不起作用:
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() (然后进入上面的失败),但它从未命中写方法。只是完全跳过了。
这里发生什么事情?我使用的代码都是来自上述链接的所有最新的和直接的代码(截止到今天)。
发布于 2018-12-07 17:43:52
感谢来自公共存储库的贡献者的帮助,问题是包含基本类型所需的序列化步骤。因此,与其简单地:
g.toJson(d);它必须是:
g.toJson(d, Shape.class);我试过g.toJson(d, Diamond.class),但这对输出没有任何影响。希望这能帮到别人!
发布于 2019-03-05 10:50:38
来自rjcarr的解决方案(在调用toJson中包括类对象)并不实用,因为您通常将多态对象作为其他对象的成员或列表中的元素。
事实上,RuntimeTypeAdapterFactory中有一个bug。在这个github哨所中,用户ultraon提出了一种对我有用的解决方案:
替换
if (type.getRawType() != baseType)使用
if (null == type || !baseType.isAssignableFrom(type.getRawType()))在第185行,方法create的类RuntimeTypeAdapterFactory。
现在,类型属性包含在JSON中。
https://stackoverflow.com/questions/53665467
复制相似问题