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

在RecyclerView中展示OkHttp+Gson获取的GET数据时出现类型转换异常

解决OkHttp+Gson解析后RecyclerView展示的Class Cast Exception问题

我来帮你排查这个类型转换异常的问题,这类问题大多出在数据解析的类型匹配或者RecyclerView Adapter的泛型适配上,咱们一步步拆解解决:

1. 先揪出最可能的根源:Gson解析后的数组转List错误

从你的代码片段看,你定义了Hero[] heroes和List<Hero> heroList,很多人会在这里踩坑——直接把数组强转成List,比如写heroList = (List<Hero>) Arrays.asList(heroes);,这其实是错误的!

正确的做法有两种:

  • 把数组转成可修改的ArrayList:
    // 先解析成Hero数组
    heroes = new Gson().fromJson(response.body().string(), Hero[].class);
    // 再转成ArrayList,避免强转问题
    heroList = new ArrayList<>(Arrays.asList(heroes));
    
  • 或者直接让Gson解析成List类型:
    // 借助TypeToken获取List<Hero>的类型
    Type heroListType = new TypeToken<List<Hero>>(){}.getType();
    // 直接解析为List<Hero>
    heroList = new Gson().fromJson(response.body().string(), heroListType);
    

2. 检查RecyclerAdapter的泛型是否匹配

你的Adapter必须是针对Hero类型的,不能混用String类型的列表(比如你代码里的demo)。举个正确的Adapter定义示例:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
    // 泛型必须是List<Hero>,不能是List<String>
    private List<Hero> heroList;

    // 构造方法接收List<Hero>
    public RecyclerAdapter(List<Hero> heroList) {
        this.heroList = heroList;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // 这里获取的是Hero对象,不是String!
        Hero currentHero = heroList.get(position);
        // 绑定Hero的属性到UI,比如名字、图片
        holder.heroNameTv.setText(currentHero.getName());
        // ...其他UI绑定逻辑
    }

    // ViewHolder和其他方法省略...
}

3. 初始化Adapter时别传错列表

你代码里有个List<String> demo,一定要确保初始化Adapter时传入的是heroList,而不是不小心传成了demo:

// 解析完成后,在UI线程更新RecyclerView
runOnUiThread(() -> {
    adapter = new RecyclerAdapter(heroList); // 这里必须传heroList
    recyclerView.setAdapter(adapter);
    // 别忘了设置LayoutManager,否则RecyclerView不会显示
    recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
});

4. 最后检查子线程更新UI的问题

OkHttp的回调是在子线程执行的,所以更新RecyclerView必须切换到UI线程,用runOnUiThread包裹,否则不仅可能报错,数据也不会显示。

给你贴一段完整的OkHttp请求+解析+Adapter初始化的正确代码片段参考:

client = new OkHttpClient();
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();

Request request = new Request.Builder().url(URL).build();
client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        progressDialog.dismiss();
        runOnUiThread(() -> Toast.makeText(MainActivity.this, "请求失败,请重试", Toast.LENGTH_SHORT).show());
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        progressDialog.dismiss();
        if (response.isSuccessful()) {
            String jsonResponse = response.body().string();
            // 直接解析为List<Hero>
            Type listType = new TypeToken<List<Hero>>(){}.getType();
            heroList = new Gson().fromJson(jsonResponse, listType);

            // 切换到UI线程更新RecyclerView
            runOnUiThread(() -> {
                adapter = new RecyclerAdapter(heroList);
                recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
                recyclerView.setAdapter(adapter);
            });
        }
    }
});

按照这几步排查,应该就能解决你的Class Cast Exception问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:17:30