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

如何将继承自Java ArrayList的SkmeList类序列化为JSON?

嘿,这个问题我碰到过好多次——因为你的SkmeList继承了ArrayList,常规的JSON序列化库(比如Jackson、Gson)默认会把它当成纯数组来处理,直接忽略你自定义的skmeMajor、skmeMinor、skmeTable这些字段。下面给你两种主流库的解决方案,按需选就行:

方案1:用Jackson序列化(推荐如果项目用Spring的话)

Jackson默认会把集合类当成数组序列化,所以我们需要告诉它把SkmeList当成对象来处理,同时暴露集合里的元素:

方法A:通过注解调整序列化行为

给SkmeList类加上@JsonFormat(shape = JsonFormat.Shape.OBJECT)注解,再添加一个方法返回集合内的元素:

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonGetter;
import java.util.ArrayList;

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public class SkmeList extends ArrayList<SkmeStatement> {
    private static final long serialVersionUID = 1L;
    private int skmeMajor = 0;
    private int skmeMinor = 0;
    private String skmeTable = null;

    // 你的现有getter/setter方法不变

    @JsonGetter("statements")
    public ArrayList<SkmeStatement> getStatements() {
        return this;
    }
}

这样序列化后,你会得到一个包含statements数组(存列表元素)和skmeMajor、skmeMinor、skmeTable字段的JSON对象。

方法B:优先用组合代替继承(更符合OOP原则)

如果可以修改类结构,别直接继承ArrayList,而是把它作为类的一个成员变量,这样序列化会自动包含所有字段,省心又规范:

import java.util.ArrayList;
import java.util.List;

public class SkmeList {
    private static final long serialVersionUID = 1L;
    private int skmeMajor = 0;
    private int skmeMinor = 0;
    private String skmeTable = null;
    // 用组合代替继承
    private List<SkmeStatement> statements = new ArrayList<>();

    // 添加操作集合的方法,比如:
    public boolean add(SkmeStatement stmt) {
        return statements.add(stmt);
    }

    // 你的现有getter/setter方法,加上statements的getter
    public List<SkmeStatement> getStatements() {
        return statements;
    }

    // 其他getter/setter...
}

这种方式不需要额外配置,Jackson会直接把所有字段序列化出来。

方案2:用Gson序列化

Gson同样默认把继承集合的类当成数组,所以需要自定义一个序列化器:

步骤1:写自定义序列化器

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;

public class SkmeListSerializer implements JsonSerializer<SkmeList> {
    @Override
    public JsonElement serialize(SkmeList src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject jsonObj = new JsonObject();
        // 序列化自定义字段
        jsonObj.addProperty("skmeMajor", src.getSkmeMajor());
        jsonObj.addProperty("skmeMinor", src.getSkmeMinor());
        jsonObj.addProperty("skmeTable", src.getSkmeTable());
        // 序列化集合里的元素
        JsonArray stmtArray = new JsonArray();
        for (SkmeStatement stmt : src) {
            stmtArray.add(context.serialize(stmt));
        }
        jsonObj.add("statements", stmtArray);
        return jsonObj;
    }
}

(注意:这里假设你给skmeMajor和skmeMinor补全了getter方法,如果没有的话,要么加getter,要么把字段改成public,或者用反射访问)

步骤2:注册序列化器并使用

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {
    public static void main(String[] args) {
        SkmeList list = new SkmeList();
        list.setTable("user_table");
        list.setMajor(1);
        list.add(new SkmeStatement()); // 假设你有这个类的实例

        // 注册自定义序列化器
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(SkmeList.class, new SkmeListSerializer())
                .create();
        // 转成JSON
        String json = gson.toJson(list);
        System.out.println(json);
    }
}

最后提醒一句:如果SkmeStatement类本身有非public字段,也要确保JSON库能访问到——要么加getter,要么给字段加对应的注解(比如Jackson的@JsonProperty,Gson不需要额外配置只要字段不是private或者有getter)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:24:40