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

Gson序列化反序列化含字符串数组POJO的数组时子数组解码失败求助

问题分析与解决方案

你的问题核心在于Item类中types字段使用了具体的ArrayList<String>类型,而Gson默认反序列化集合时会生成自己的List实现类,导致无法匹配setTypes(ArrayList<String>)方法,最终types字段始终为null。


解决方案1:面向接口编程(推荐)

把Item类中的types字段、getter和setter都改为使用List<String>接口,而不是具体的ArrayList实现。这样Gson可以自由适配任何List类型,不会出现类型不匹配的问题。

修改后的Item类:

public class Item {
    private String name;
    private List<String> types; // 改为List接口

    public Item() { super(); }
    public Item(String name, List<String> types) { // 参数改为List
        this.name = name;
        this.types = types;
    }

    public void setName(String name) { this.name = name; }
    public String getName() { return name; }

    public void setTypes(List<String> types) { // 参数改为List
        this.types = types;
    }
    public List<String> getTypes() { // 返回值改为List
        return types;
    }
}

对应的ItemData类也可以同步修改(可选,但更规范):

public class ItemData {
    private List<Item> items = new ArrayList<>(); // 改为List接口
    public void setItems(List<Item> items) { this.items = items; }
    public List<Item> getItems() { return items; }
}

之后你原本的反序列化代码(比如使用ItemData的方式)就可以正常工作了:

ItemData data = new Gson().fromJson(json, ItemData.class);
List<Item> items = data.getItems();

解决方案2:强制Gson使用ArrayList序列化/反序列化

如果你坚持要使用ArrayList而不是List接口,可以通过GsonBuilder配置自定义的类型适配器,让Gson在处理List时强制使用ArrayList:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(List.class, new TypeAdapter<List<?>>() {
        @Override
        public void write(JsonWriter out, List<?> value) throws IOException {
            // 序列化逻辑,直接委托给默认适配器
            new Gson().toJson(value, value.getClass(), out);
        }

        @Override
        public List<?> read(JsonReader in) throws IOException {
            // 反序列化时强制返回ArrayList
            return new Gson().fromJson(in, ArrayList.class);
        }
    })
    .create();

// 之后用这个gson实例反序列化
ItemData data = gson.fromJson(json, ItemData.class);
ArrayList<Item> items = (ArrayList<Item>) data.getItems();

不过这种方式不如第一种优雅,因为它破坏了面向接口的设计原则,而且可能带来其他潜在的类型问题。


为什么会出现这个问题?

Gson在反序列化集合类型时,默认不会严格按照你声明的具体实现类(比如ArrayList)来创建对象,而是会生成它自己的内部List实现(比如com.google.gson.internal.LinkedTreeList)。当你的setter方法只接受ArrayList类型时,Gson无法将这个内部List转换为ArrayList,因此不会调用setter,导致types字段保持为null。

而使用List接口的话,任何List实现类都可以赋值给该字段,自然就解决了类型不匹配的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:37:55