GSON 接口序列化列表 [英] Serializing List of Interfaces GSON

查看:34
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆