如何让Gson.fromJson()为null字段返回空列表而非null?
解决Gson反序列化时null列表转为空列表的问题
问题原因分析
- @JsonSetter注解无效:该注解属于Jackson框架,Gson不支持此注解,因此无法生效。
- 自定义反序列化器写法错误:你之前的反序列化器内部直接
new Gson(),会创建未注册任何适配器的新实例,导致递归解析异常;且未通过GsonBuilder注册该反序列化器,Gson并未实际使用它。 - Gson对final字段的处理:Gson默认会通过反射修改final字段的值,即便你初始化了
list = new ArrayList<>(),当JSON中该字段为null时,Gson仍会将其覆盖为null。
全局解决方案(适合大量列表场景)
方法1:注册全局Collection反序列化器
编写正确的反序列化器,针对所有Collection子类(List、Set等)统一处理null值,转为对应类型的空集合:
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; class CollectionNullDeserializer implements JsonDeserializer<Collection<?>> { @Override public Collection<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // 处理JSON null的情况 if (json.isJsonNull()) { // 根据原始类型返回对应空集合 if (typeOfT instanceof ParameterizedType) { Type rawType = ((ParameterizedType) typeOfT).getRawType(); if (List.class.isAssignableFrom((Class<?>) rawType)) { return new ArrayList<>(); } else if (Set.class.isAssignableFrom((Class<?>) rawType)) { return new HashSet<>(); } } // 默认返回ArrayList return new ArrayList<>(); } // 非null时,用上下文正常解析 return context.deserialize(json, typeOfT); } }
通过GsonBuilder注册该反序列化器,全局生效:
// 创建Gson实例时注册全局适配器 Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(Collection.class, new CollectionNullDeserializer()) .create(); // 反序列化测试 User from = gson.fromJson(x, User.class); System.out.println(from); // 输出:TestApplication.User(userName=test, email=dan@gmail.com, list=[])
方法2:利用Gson的InstanceCreator(可选)
如果希望保留类中已初始化的final集合实例,可注册InstanceCreator,当Gson需要创建集合实例时,返回已初始化的对象:
import com.google.gson.InstanceCreator; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; class CollectionInstanceCreator implements InstanceCreator<Collection<?>> { @Override public Collection<?> createInstance(Type type) { // 返回空集合实例 return new ArrayList<>(); } }
注册方式:
Gson gson = new GsonBuilder() .registerTypeHierarchyAdapter(Collection.class, new CollectionInstanceCreator()) .create();
注:此方法适合希望Gson始终使用空集合而非null的场景,对于非null的JSON集合,仍会正常填充数据。
验证效果
使用上述方法后,当JSON中list字段为null时,反序列化后的对象会得到空列表([]),而非null,且无需为每个列表字段单独配置。
内容的提问来源于stack exchange,提问作者Bogdan Maceasa
相关产品推荐
相关产品推荐

