我正在使用gson反序列化对象,我告诉 gson 接口(interface)类而不是我想要的对象的实现类。我注册了一个 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 错误,还是还有其他问题?
最佳答案
如果您调试它并在 createInstance
中放置断点并单步执行 gson 代码,您应该会看到问题。
实例化后,gson 尝试填充 ReflectiveTypeAdapterFactory
中的所有绑定(bind)字段。在您的情况下,绑定(bind)字段映射为空。这是因为它无法检查您的界面中的字段。
来自 ReflectiveTypeAdapterFactory
中的 getBoundFields
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
if (raw.isInterface()) {
return result;
}
因此,如果您告诉 gson 反序列化的类型没有零参数构造函数可供 gson 调用,则实例创建者更合适。
关于java - 当实例创建者注册到 gson 时,字段不会反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30766656/