com.google.gson.internal.LinkedTreeMap cannot be cast to xxx

当尝试将Json数据转换为特定类型时,遇到'com.google.gson.internal.LinkedTreeMap cannot be cast to xxx'的错误。原因是Java泛型类型擦除,未指定明确的类型导致。解决方案是在接口处理类中为泛型指定确切的类型,如RootBean<List<DataBean>>,确保数据能正确解析。涉及的代码包括Api请求层、Contract层、Model层、Presenter层和UI层。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

Gson泛型解析时Json报错:com.google.gson.internal.LinkedTreeMap cannot be cast to xxx

先看下返回的Json数据格式

{
    "code": 200,
    "data": [
        {
            "id": null,
            "type": "free",
            "name": "免费数字教材",
            "totals": null,
            "books": [
                {
                    "ebook_type": "0",
                    "author": "测试作者",
                    "isfree": "0",
                    "isbn": "9787040144390",
                    "title": "测试标题1",
                    "type": 0,
                    "url": "http://d7.ixdzs.com/66/66746/66746.epub",
                    "download_count": 234,
                    "cover": "https://pic4.zhimg.com/017d7c47843b8816a0ab583d37628947_xld.jpg",
                    "addtime": 1493869462000,
                    "id": 4,
                    "press": "测试出版社",
                    "introduction": "简介",
                    "likes": 1
                }
                ...
            ]
        }
    ],
    "msg": "ok",
    "app_key": null
}

然后是通用的接口处理类

public class RootBean<T> extends BaseEntity.BaseBean {

    /**
     * code : 200
     * data : []
     * msg : ok
     * app_key : null
     */

    private int code;
    private String msg;
    private Object app_key;
    private T data;


    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getApp_key() {
        return app_key;
    }

    public void setApp_key(Object app_key) {
        this.app_key = app_key;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }


    @Override
    public String toString() {
        return "RootBean{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", app_key=" + app_key +
                ", data=" + data +
                '}';
    }
}

错误原因

原因是没有为泛型指定明确的类型,导致Java类型擦除异常。

解决

在该接口所有使用RootBean< T >的方法或参数中指定T的类型,即RootBean< List < DataBean > >,List < DataBean >为最终要取出的数据。

贴一下相关的代码:

Api请求层

  /**
     * 首页推荐 List
     * http://192.168.100.158/portal/app/find/recommends
     *
     * @return
     */
    @GET("find/recommends")
    Observable<RootBean<List<DataBean>>> findRecommends();

Contract 层

public interface FindContract {
    interface Model extends BaseModel {
        /**
         * 获取发现页面的数据
         *
         * @return
         */
        Observable<RootBean<List<DataBean>>> findRecommends();
    }

    interface View extends BaseView {
        /**
         * 用于页面显示数据
         *
         * @param rootBean
         */
        void findRecommends(RootBean<List<DataBean>> rootBean);

        /**
         * 显示错误提示
         *
         * @param e
         */
        void displayError(Throwable e);
    }

    abstract class Presenter extends BasePresenter<Model, View> {
        abstract void findRecommends();

        @Override
        public void onAttached() {

        }
    }
}

Model层

public class FindModel implements FindContract.Model {
    @Override
    public Observable<RootBean<List<DataBean>>> findRecommends() {
        return ApiManager.getInstance().mApiService.findRecommends()
                .compose(RxSchedulers.<RootBean<List<DataBean>>>applySchedilers());
    }
}

Presenter层

public class FindPresenter extends FindContract.Presenter {
    @Override
    public void findRecommends() {
        mModel.findRecommends().subscribe(new Observer<RootBean<List<DataBean>>>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                mView.displayError(e);
            }

            @Override
            public void onNext(RootBean<List<DataBean>> rootBean) {
                mView.findRecommends(rootBean);
            }
        });

    }
}

UI层

public class FindFragment extends BaseFragment<FindPresenter, FindModel> implements FindContract.View {

    /*首页数据的集合*/
    List<DataBean> mDataBeanList;
    List<BannersBean> mBannersBeanList;
    List<BooksBean> mBooksBeanList;//纸质教材集合
    /*复杂布局的适配器*/
    private MultiTypeAdapter mAdapter;
    private Items mItems;//Items 等同于 ArrayList<Object>

    /*控件*/
    @BindView(R.id.rv_content)
    RecyclerView content_rv;//根RecyclerView
    @BindView(R.id.swipeRefresh)
    SwipeRefreshLayout swipeRefreshLayout;//刷新控件

    public FindFragment() {
    }

    public static FindFragment newInstance() {
        FindFragment fragment = new FindFragment();
        return fragment;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_find;
    }

    @Override
    protected void initView() {
        /*刷新下拉刷新样式*/
        swipeRefreshLayout.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary,
                R.color.red);//设置刷新控件的颜色
        //注册类型和View的对应关系
        mAdapter = new MultiTypeAdapter();
        //轮播图
        mAdapter.register(BannersListBean.class, new BannersViewBinder(mContext));
        //列表标题头
        mAdapter.register(HeaderBean.class, new HeaderViewBinder());
        //教材推荐
        mAdapter.register(BooksListBean.class, new BooksViewBinder(mContext));
        /*设置RV布局方式*/
        LinearLayoutManager layoutManager = new LinearLayoutManager(mContext);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        content_rv.setLayoutManager(layoutManager);
        content_rv.setAdapter(mAdapter);


    }

    @Override
    protected void initData() {
        swipeRefreshLayout.setRefreshing(true);//加载界面时刷新
        mPresenter = new FindPresenter();
        mPresenter.setMV(new FindModel(), this);
        mPresenter.findRecommends();//获取推荐信息
    }

    @Override
    public void findRecommends(RootBean<List<DataBean>> rootBean) {
        // 加载完数据设置为不刷新状态,将下拉进度收起来
        swipeRefreshLayout.setRefreshing(false);
        if (rootBean != null) {
            mBannersBeanList = new ArrayList<>();
            //添加轮播图数据
            mBannersBeanList.add(new BannersBean("https://pic4.zhimg.com/v2-0a5e49bf27ffc7fbc13350e29408e9bf.jpg",
                    "https://www.zhihu.com/publications/book/119554452"));

            //mDataBeanList = JsonUtil.stringToArray(rootBean.getData().toString(), DataBean[].class);
            mDataBeanList = rootBean.getData();
            //模拟加载数据
            mItems = new Items();
            for (DataBean d : mDataBeanList) {
                //保证只填充一次
                if ("free".equals(d.getType())) {
                    mItems.add(new BannersListBean(mBannersBeanList));
                }
                mItems.add(new HeaderBean(d.getName()));
                mBooksBeanList = d.getBooks();
                mItems.add(new BooksListBean(mBooksBeanList));
            }
            mAdapter.setItems(mItems);
            mAdapter.notifyDataSetChanged();
        }
    }


    @Override
    public void displayError(Throwable e) {
        // 加载完数据设置为不刷新状态,将下拉进度收起来
        swipeRefreshLayout.setRefreshing(false);
        Timber.tag(TAG).e(e.toString());
    }

    @Override
    protected void initEvent() {
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mPresenter.findRecommends();

            }
        });
    }

参考

http://blog.youkuaiyun.com/anddroid_lanyan/article/details/46561341

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼诺和尼可

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值