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

如何用GSON解析多子类嵌套列表JSON?含类结构等技术疑问

日程JSON存储与解析问题解答

问题1:如何使用GSON.fromJson()解析该JSON数据?

GSON处理带继承关系的多态解析需要额外配置,同时要解决Calendar类型的序列化/反序列化问题,步骤如下:

  1. 配置多态识别:用GSON的RuntimeTypeAdapterFactory给每个子类指定标识字段(比如type),JSON中每个对象必须携带该字段用于区分子类。
  2. 自定义Calendar适配器:GSON默认不支持Calendar,需编写适配器将其转为时间戳存储。
  3. 创建Gson实例并解析:

示例代码:

// 1. 注册多态子类
val scheduleItemFactory = RuntimeTypeAdapterFactory.of(ScheduleItem::class.java, "type")
    .registerSubtype(DayScheduleItem::class.java, "day")
    .registerSubtype(WeekDayScheduleItem::class.java, "weekday")
    .registerSubtype(ExceptionItem::class.java, "exception")

// 2. Calendar类型适配
class CalendarTypeAdapter : TypeAdapter<Calendar>() {
    override fun write(out: JsonWriter, value: Calendar) {
        out.value(value.timeInMillis)
    }

    override fun read(`in`: JsonReader): Calendar {
        val millis = `in`.nextLong()
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = millis
        return calendar
    }
}

// 3. 解析JSON
val gson = GsonBuilder()
    .registerTypeAdapter(Calendar::class.java, CalendarTypeAdapter())
    .registerTypeAdapterFactory(scheduleItemFactory)
    .create()

val jsonStr = "你的JSON字符串"
val scheduleList: List<List<ScheduleItem>> = gson.fromJson(
    jsonStr,
    object : TypeToken<List<List<ScheduleItem>>>() {}.type
)

注意:原始JSON需要补充每个对象的type字段,比如DayScheduleItem对应的JSON要添加"type": "day"。

问题2:是否需要简化现有的类结构?

需要优化,主要方向:

  • 清理冗余代码:Kotlin类默认生成getter/setter,ScheduleItem中的手动实现完全多余,可直接删除。
  • 规范数据类:把WeekDayScheduleItem的isOpen移到主构造函数,改成标准数据类:
    data class WeekDayScheduleItem(
        var name: String,
        var isOpen: Boolean = false
    ): ScheduleItem()
    
  • 替换旧API:Calendar是Java过时API,建议换成Kotlin的LocalTime(仅需时分的场景)或LocalDateTime,避免时区和序列化隐患。
  • 明确结构:如果嵌套列表的三个子列表分别对应三类日程,可直接用一个聚合数据类替代嵌套结构:
    data class ScheduleConfig(
        val dayItems: List<DayScheduleItem>,
        val weekDayItems: List<WeekDayScheduleItem>,
        val exceptionItems: List<ExceptionItem>
    )
    
    这样类型更明确,解析和使用更直观。

问题3:是否需要更换为Moshi等其他JSON解析库?

不是必须,但如果项目以Kotlin为主,Moshi的体验更优:

  • Kotlin原生适配:默认支持data class、空安全、默认值,无需额外配置。
  • 多态解析更简洁:通过PolymorphicJsonAdapterFactory实现多态,代码量更少。
  • 时间API支持友好:原生兼容Java 8时间API或Kotlinx-datetime,无需手动编写适配器。

如果已经在使用GSON且不想引入新依赖,GSON通过配置也能满足需求;如果是新项目或对Kotlin兼容性要求高,建议换成Moshi。

问题4:是否需要调整当前的JSON结构?

需要,当前嵌套列表语义模糊,依赖子列表位置区分类型,容易出错且可读性差。建议改成键值对结构,明确每个类型的列表:

{
  "dayScheduleItems": [
    {"type": "day", "hourAndMin": 1699999999999, "id": 1, "data": []},
    {"type": "day", "hourAndMin": 1700000000000, "id": 2, "data": []}
  ],
  "weekDayScheduleItems": [
    {"type": "weekday", "name": "Monday", "isOpen": true, "id": 3, "data": []}
  ],
  "exceptionItems": []
}

这种结构无需依赖顺序,类型清晰,解析时可直接映射到对应实体类,维护和扩展更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:35:40