GSON 接口序列化列表 [英] Serializing List of Interfaces GSON
问题描述
我在 GSON 中遇到了一些奇怪的行为.
I came across some weird behavior in GSON.
如果我有以下类结构:
public interface Animal {
public void nothing();
}
public class Cat implements Animal {
private String name;
public Cat(String name) {
super();
this.name = name;
}
public Cat(){}
@Override
public void nothing() {
// TODO Auto-generated method stub
};
}
public class Dog implements Animal {
private String name;
public Dog(String name) {
super();
this.name = name;
}
public Dog(){}
@Override
public void nothing() {
// TODO Auto-generated method stub
};
}
我可以做到:
ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(new Cat("Betty"));
animals.add(new Dog("Fred"));
System.out.println(gson.toJson(animals));
并得到这个输出:
[{"name":"Betty"},{"name":"Fred"}]
但是,如果我将 animals
放入包含类中:
However, if I put animals
into a containing class:
public class Container {
List<Animal> animals = new ArrayList<Animal>();
public void addAnimal(Animal a){
animals.add(a);
}
}
并调用:
Container container = new Container();
container.addAnimal(new Cat("betty"));
System.out.println(gson.toJson(container));
我明白了:
{"animals":[{}]}
看起来GSON可以序列化接口列表List
,当该列表本身时,但当列表包含在另一个类中时,GSON有问题.
It looks like GSON can serialize a list of an interface List<Interface>
when that list is by itself, but when the list is contained in another class, GSON has problems.
知道我做错了什么吗?
作为旁注,我可以使用自定义反序列化器将 json 字符串正确反序列化为正确的类型.是序列化给我带来了问题.
As a side note, I can correctly deserialize a json string into the correct type using a custom deserializer. It's the serializing that is giving me issues.
谢谢
推荐答案
它远非漂亮,但我现在使用的解决方案是使用
It's far from pretty, but the solution I'm using for now is to use
JsonObject jsonObject = gson.toJsonTree(container).getAsJsonObject();
构建一个 JsonObject.然后我打电话:
to build a JsonObject. Then I call:
jsonObject.remove("animals");
jsonObject.add("animals",gson.toJsonTree(container.getAnimals()));
和 waa laa,正确的 json 形式的对象.
and waa laa, the object in correct json form.
加分项:我有一个嵌套容器列表,所以我必须构造一个 JsonArray 以便我可以迭代我的容器并在每个容器上调用我的自定义 toJson().
Bonus points: I had a list of nested containers, so I had to construct a JsonArray so that I could iterate over my containers and call my custom toJson() on each.
故事的寓意:使用
jsonObject.remove();
jsonObject.add(propertyName, property);
使用 JsonArray 欺骗和迭代容器列表(仅在列表上使用 toJson() 不会调用您在子容器上的特殊方法).
trick and iterate over a List of containers using a JsonArray (just using toJson() on the list doesn't call your special method on children containers).
肯定仍在寻找更自然的解决方案.
Definitely still looking for a more natural solution.
快乐编码
这篇关于GSON 接口序列化列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!