java - 为什么 Gson.toJson 会将泛型字段序列化为空的 JSON 对象?

标签 java gson

我有一个包含 T 类型字段的泛型类,Gson 将该字段序列化为一个空对象。我在下面包含了代码来演示这个问题。读回 JSON 似乎没问题(只要您提供正确的类型标记)。

import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class GsonIssue {
    static class AbstractThing {
        private String fieldA = "valueA";

        public String getFieldA() {
            return fieldA;
        }

        public void setFieldA(String fieldA) {
            this.fieldA = fieldA;
        }

        @Override
        public String toString() {
            return "AbstractThing [fieldA=" + fieldA + "]";
        }
    }

    static class Thing extends AbstractThing {
        private String fieldB = "valueB";

        @Override
        public String toString() {
            return "Thing [fieldB=" + fieldB + ", fieldA=" + getFieldA() + "]";
        }
    }

    static class Wrapper<T extends AbstractThing> {
        private T abstractThing;
        private String standardField = "standard value";

        public Wrapper(T abstractThing) {
            this.abstractThing = abstractThing;
        }

        @Override
        public String toString() {
            return "Wrapper [abstractThing=" + abstractThing + ", standardField=" + standardField + "]";
        }
    }

    public static void main(String[] args) {
        Wrapper<Thing> wrapper = new Wrapper<Thing>(new Thing());

        Gson gson = new Gson();
        String json = gson.toJson(wrapper);
        System.out.println(json);
        // prints : {"abstractThing":{},"standardField":"standard value"}
        // so standardField is correctly serialized but not abstractThing.

        // but if we manually construct the expected json string, and parse it back, we get the expected object structure
        json = "{\"standardField\": \"some text\", " +
                "\"abstractThing\":{\"fieldB\" : \"arb value\", \"fieldA\" : \"another arb value\"}}";

        Type type = new TypeToken<Wrapper<Thing>>() {}.getType();
        Object fromJson = gson.fromJson(json, type);
        System.out.println(fromJson);
        // prints : Wrapper [abstractThing=Thing [fieldB=arb value, fieldA=another arb value], standardField=some text]
        // which is as expected
    }
}

最佳答案

来自他们的文档:

When you call toJson(obj), Gson calls obj.getClass() to get information on the fields to serialize. Similarly, you can typically pass MyClass.class object in the fromJson(json, MyClass.class) method. This works fine if the object is a non-generic type. However, if the object is of a generic type, then the Generic type information is lost because of Java Type Erasure

You can solve this problem by specifying the correct parameterized type for your generic type. You can do this by using the TypeToken class.

他们为 List<T> 给出了以下示例:

Type listType = new TypeToken<List<String>>() {}.getType();
gson.toJson(myStrings, listType);

因此对于您的代码,您需要...

Type myType = new TypeToken<Wrapper<Thing>>() {}.getType();
String json = gson.toJson(wrapper, myType);

https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Gener

关于java - 为什么 Gson.toJson 会将泛型字段序列化为空的 JSON 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7299669/

相关文章:

java - Spring DI : Injection of FileInputStream in Constructor using annotation

android - 为什么在 android studio 中使用 gson 解析 json 对象时得到空值?

android - 改造 - 预期为 BEGIN_ARRAY 但实际为 BEGIN_OBJECT?

java - Android - 如何在 TextView 中打印结果?

java - Realm :更改字段名称以进行迁移

java - 使用Gson解析JSON数字数组

java - 使用 GSON 创建 JSON 字符串

java - 当空字段包含子字段时,GSON 转换错误

java - 静态匿名类在Java中就一定是错误的吗?

java - SOAP Web 服务 : Axis2 1. 6.2