为什么Gson.toJson将通用字段序列化为空的JSON对象?

我有一个包含T类型字段的generics类,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 { 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 wrapper = new Wrapper(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>() {}.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 } } 

从他们的文档:

当你调用toJson(obj)时,Gson调用obj.getClass()来获取有关要序列化的字段的信息。 类似地,您通常可以在fromJson(json,MyClass.class)方法中传递MyClass.class对象。 如果对象是非generics类型,则此方法可以正常工作。 但是,如果对象是generics类型,则由于Java类型擦除而丢失通用类型信息

您可以通过为generics类型指定正确的参数化类型来解决此问题。 您可以使用TypeToken类来完成此操作。

他们为List提供以下示例:

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

所以对于你的代码,你需要……

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

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