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

Retrofit调用接口报java.lang.IllegalStateException:预期对象却得数组

解决Retrofit请求时的java.lang.IllegalStateException异常

咱先把这个异常的本质说透:你用Retrofit声明的返回数据类型,和接口实际返回的JSON结构完全不匹配。具体到你的报错Expected BEGIN_OBJECT but was BEGIN_ARRAY,意思就是Gson解析器本来以为要解析一个JSON对象(用{}包裹的结构),结果收到的却是一个JSON数组(用[]包裹的结构),直接懵圈报错了。

下面给你一步步排查解决的方法:

1. 先搞清楚接口返回的JSON到底是什么结构

直接访问你提供的接口链接,看看返回的内容是下面哪种:

  • 第一种:纯数组结构(比如[{"classId":1, "className":"数学"}, ...])
  • 第二种:包含数组的对象结构(比如{"code":200, "data": [{"classId":1, ...}]})

这一步是关键,搞清楚结构才能针对性改代码。

2. 针对不同结构修改代码

情况一:接口返回纯JSON数组

如果接口返回的是纯数组,那你代码里Call<List<AllRespoClass>>的声明是对的,但问题大概率出在AllRespoClass的定义上:

  • 检查字段类型:比如JSON里某个字段是数组(比如"students": [{"name":"张三"}]),但你在AllRespoClass里把它定义成了单个对象(private Student students;),这时候就会报同样的错,要改成private List<Student> students;。
  • 检查字段名匹配:如果JSON键是class_id,而你的实体类字段是classId,记得加@SerializedName注解映射:
    @SerializedName("class_id")
    private int classId;
    
  • 别忘了给实体类加无参构造方法,Gson解析时需要这个。

正确的AllRespoClass示例:

public class AllRespoClass {
    @SerializedName("class_id")
    private int classId;
    @SerializedName("class_name")
    private String className;

    public AllRespoClass() {}

    // Getter和Setter方法
    public int getClassId() { return classId; }
    public void setClassId(int classId) { this.classId = classId; }
    public String getClassName() { return className; }
    public void setClassName(String className) { this.className = className; }
}

情况二:接口返回包含数组的JSON对象

如果接口返回的是带外层的对象(比如有status、data这类字段),那你直接用List<AllRespoClass>就不对了,得定义一个外层实体类来包裹整个结构:

先写外层类ClassResponse:

public class ClassResponse {
    private String status;
    @SerializedName("classes")
    private List<AllRespoClass> classList;

    public ClassResponse() {}

    // Getter和Setter
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public List<AllRespoClass> getClassList() { return classList; }
    public void setClassList(List<AllRespoClass> classList) { this.classList = classList; }
}

然后把Retrofit的Call改成:

Call<ClassResponse> allInputDataApiCall = apiGet.getDataInput();

最后修改回调逻辑:

allInputDataApiCall.enqueue(new Callback<ClassResponse>() {
    @Override
    public void onResponse(Call<ClassResponse> call, Response<ClassResponse> response) {
        if (response.isSuccessful() && response.body() != null) {
            List<AllRespoClass> allClasses = response.body().getClassList();
            // 这里就可以正常处理数据了
        }
    }

    @Override
    public void onFailure(Call<ClassResponse> call, Throwable t) {
        // 处理请求失败的情况
        t.printStackTrace();
    }
});

3. 最后再检查两个细节

  • 确保你的Retrofit实例配置了Gson转换器,没有这个的话解析会出问题:
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://elearnup.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    
  • 如果接口返回的JSON有嵌套结构,一定要把每个层级的实体类都定义正确,不能漏。

内容的提问来源于stack exchange,提问作者Manoj Budha Ayer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:33:42