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

Kotlin中GSON解析报错:Expected BEGIN_OBJECT but was BEGIN_ARRAY

解决Gson解析JSON数组到自定义对象的异常问题

错误原因

你遇到的com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY异常,核心是数据结构不匹配:

  • API返回的是JSON数组(格式为["/title/tt1649418/", "/title/tt10954984/"])
  • 你定义的PopularMovies是对象类型(对应JSON的{"popularMovies": [...]}结构)
    Gson尝试将数组解析为对象,自然触发语法错误。

三种解决方案

方案一:直接解析为字符串列表(最简洁)

既然API返回的就是字符串数组,跳过自定义对象包装,直接解析成List<String>:

val gson = Gson()
val movieIds: List<String> = gson.fromJson(
    jsonString,
    object : TypeToken<List<String>>() {}.type
)

方案二:手动包装为自定义对象

如果必须使用PopularMovies类,先解析数组再手动构造对象:

val gson = Gson()
// 先解析成字符串列表
val movieIdsList: List<String> = gson.fromJson(
    jsonString,
    object : TypeToken<List<String>>() {}.type
)
// 构造自定义对象
val popularMovies = PopularMovies(ArrayList(movieIdsList))

方案三:自定义TypeAdapter自动适配

适合需要反复解析该结构的场景,编写TypeAdapter让Gson自动完成数组到对象的转换:

class PopularMoviesAdapter : TypeAdapter<PopularMovies>() {
    override fun write(out: JsonWriter, value: PopularMovies) {
        Gson().toJson(value.popularMovies, out)
    }

    override fun read(`in`: JsonReader): PopularMovies {
        val movieIds = Gson().fromJson<List<String>>(
            `in`,
            object : TypeToken<List<String>>() {}.type
        )
        return PopularMovies(ArrayList(movieIds))
    }
}

使用时注册Adapter:

val gson = GsonBuilder()
    .registerTypeAdapter(PopularMovies::class.java, PopularMoviesAdapter())
    .create()
val popularMovies: PopularMovies = gson.fromJson(jsonString, PopularMovies::class.java)

推荐方案

优先选择方案一,完全贴合API返回结构,代码简洁且避免不必要的对象包装。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:03:39