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

Gson反序列化时,标记为不反序列化的字段为何为null?

Gson反序列化时标记不反序列化的final字段为null的问题分析与解决

问题原因

  1. 反序列化Entity时,Gson会识别JSON里的setting字段,重新创建Mode实例,不会复用Entity类里预先初始化好的setting对象。
  2. Mode的list是final字段,且通过@Expose(deserialize = false)标记为不参与反序列化,Gson会跳过这个字段的赋值操作。
  3. 因为Mode没有无参构造器,Gson会通过反射绕过构造器创建实例,这时final字段list会被初始化为默认值null(正常情况下final字段必须在构造器或初始化块里赋值,但反射创建实例时不会执行构造器逻辑)。

解决方案

方案1:给Mode构造器添加参数处理逻辑

修改Mode类的构造器,当传入的list为null时(因为反序列化被排除,Gson会传null),用默认值初始化:

public class Mode {
    @Expose(deserialize = false)
    public final List<String> list;

    public Mode(@SerializedName("list") List<String> list) {
        // 当list为null时使用默认列表
        this.list = list != null ? list : Arrays.asList("1", "2");
    }

    public List<String> getList() {
        return list;
    }
}

Gson默认会识别带参数的构造器,配合@SerializedName可以让构造器参数和JSON字段对应,这样反序列化时即使list被排除,也能通过构造器给final字段赋默认值。

方案2:自定义InstanceCreator创建Mode实例

写一个InstanceCreator,让Gson在创建Mode实例时直接返回带默认list的对象:

public class ModeInstanceCreator implements InstanceCreator<Mode> {
    @Override
    public Mode createInstance(Type type) {
        return new Mode(Arrays.asList("1", "2"));
    }
}

然后在Gson构建时注册这个InstanceCreator:

Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .addDeserializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                Expose annotation = f.getAnnotation(Expose.class);
                return annotation != null && !annotation.deserialize();
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        })
        .registerTypeAdapter(Mode.class, new ModeInstanceCreator())
        .create();

这样Gson反序列化Mode时,会用InstanceCreator创建实例,list就会是预设的默认值。

方案3:跳过setting字段的反序列化(如果不需要更新setting)

如果不需要从JSON更新setting的内容,只想保留Entity里初始化的setting实例,可以给setting字段加上@Expose(deserialize = false):

public class Entity {
    @Expose(deserialize = false)
    public Mode setting = new Mode(Arrays.asList("1", "2"));
}

这样Gson会跳过反序列化setting字段,直接保留原来的实例,list自然不会为null。

内容的提问来源于stack exchange,提问作者Enaium

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:33:44