You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Gson.fromJson()为null字段返回空列表而非null?

解决Gson反序列化时null列表转为空列表的问题

问题原因分析

  1. @JsonSetter注解无效:该注解属于Jackson框架,Gson不支持此注解,因此无法生效。
  2. 自定义反序列化器写法错误:你之前的反序列化器内部直接new Gson(),会创建未注册任何适配器的新实例,导致递归解析异常;且未通过GsonBuilder注册该反序列化器,Gson并未实际使用它。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:23:19