Java Gson&x27;s RuntimeTypeAdapterFactory不是';t序列化类型

Java Gson&x27;s RuntimeTypeAdapterFactory不是';t序列化类型,java,json,gson,Java,Json,Gson,我很高兴地使用gson多年,需要序列化和反序列化一些多态类型,并遇到了这个gson额外功能,这似乎正是我所需要的: 但无论我尝试什么,它都不会序列化类型字段,因此当它尝试反序列化时,自然会出现以下错误: 无法反序列化类,因为它未定义名为type的字段 即使使用文件中的演示代码对我也不起作用: class Shape { int x; int y; } class Diamond extends Shape { int width; int height; } ... Gs

我很高兴地使用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()和register()指定自定义字符串,将类型添加到toJson()调用中,甚至将对象嵌入到外部集合中,但没有任何区别

实际上,标准Gson对象和使用builder和type factory创建的对象之间的输出没有区别

我注意到,如果我调试代码并在RuntimeTypeAdapterFactory读写方法中设置断点,它将命中read()(然后到达上面的失败),但它永远不会命中write方法。完全跳过了


这是怎么回事?我使用的代码都是最新的,直接来自上面的链接(从今天开始)。

多亏了公共存储库贡献者的帮助,问题在于包含基类型所需的序列化步骤。因此,与其简单地说:

g.toJson(d);
它需要:

g.toJson(d, Shape.class);

我尝试了
g.toJson(d,Diamond.class)
,但这对输出没有影响。希望这能帮助别人

多亏了公共存储库贡献者的帮助,问题在于包含基类型所需的序列化步骤。因此,与其简单地说:

g.toJson(d);
它需要:

g.toJson(d, Shape.class);
我尝试了
g.toJson(d,Diamond.class)
,但这对输出没有影响。希望这能帮助别人

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

实际上,
RuntimeTypeAdapterFactory
中有一个bug。在中,用户ultraon提出了一个适合我的解决方案:

替换

if (type.getRawType() != baseType)

在第185行中,类
RuntimeTypeAdapterFactory
的方法
create

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

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

实际上,
RuntimeTypeAdapterFactory
中有一个bug。在中,用户ultraon提出了一个适合我的解决方案:

替换

if (type.getRawType() != baseType)

在第185行中,类
RuntimeTypeAdapterFactory
的方法
create

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