实例创建者向gson注册时未反序列化的字段

时间:2015-06-10 20:26:20

标签: java json gson

我正在使用gson来反序列化对象,我告诉gson接口类而不是我想要的对象的实现类。我注册了一个构造实现类实例的InstanceCreator

此测试演示了我遇到的问题:

public class UnexpectedGsonBehaviorTest {

    public static interface Fruits {
        List<String> getFruitList();
    }

    public static class FruitsImpl implements Fruits {

        private List<String> fruitList;

        public List<String> getFruitList() {
            return fruitList;
        }

        public String toString() {
            return "FruitsImpl{" + "fruitList=" + fruitList + '}';
        }

    }

    @Test
    public void testUseCustomFruitsInstanceCreator() {
        Gson gson = new GsonBuilder()
          .registerTypeAdapter(Fruits.class, new InstanceCreator<Fruits>(){
            public Fruits createInstance(Type type) {
                return new FruitsImpl();
            }
        }).create();
        String fruitsJson = "{\"fruitList\": [\"apples\", \"pears\", \"bananas\"]}";
        System.out.println("input: " + fruitsJson);
        Fruits fruits = gson.fromJson(fruitsJson, Fruits.class);
        System.out.println("output: " + fruits);
        assertNotNull("expect non-null fruit list", fruits.getFruitList());
    }

}

我希望反序列化FruitsImpl对象的列表成员,但事实并非如此。输出是

input: {"fruitList": ["apples", "pears", "bananas"]}
output: FruitsImpl{fruitList=null} 

并且断言失败。

如果我只使用默认的gson实例和gson.fromJson(fruitsJson, FruitsImpl.class),则列表字段会被正确反序列化。我使用gson是错误的,还是有其他问题?

1 个答案:

答案 0 :(得分:0)

如果您调试它并在createInstance内放置一个断点并进入gson代码,您应该会看到问题。

实例化后,gson尝试填充ReflectiveTypeAdapterFactory中的所有绑定字段。在您的情况下,绑定字段映射为空。这是因为它无法检查您的接口是否有字段。

来自getBoundFields

中的ReflectiveTypeAdapterFactory
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
if (raw.isInterface()) {
  return result;
}

因此,如果你告诉gson反序列化的类型没有零参数构造函数供gson调用,那么实例创建者更合适。