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

如何解决ClassCastException:String无法转为tcmb对象异常

解决ClassCastException:String无法转成tcmb对象的问题

这个异常的核心原因非常明确:你存储到SharedPreferences的是tcmb对象的字符串表示(默认toString()方法的输出),但读取时却试图把这些普通字符串直接强转成tcmb对象——String和tcmb是完全不同的类型,JVM根本无法完成这个转换,自然抛出ClassCastException。

问题根源拆解

  1. setList存储逻辑错误:
    你用valuesBuilder.append(s);拼接的是tcmb对象的默认toString()结果(通常是com.example.lscodex.ddddd.Model.tcmb@xxxxxx格式),本质上只是存了一堆字符串,而非对象本身的有效数据。
  2. getList读取逻辑错误:
    你把分割后的字符串列表itemList直接强转成List<tcmb>,相当于强制JVM把String类型当成tcmb对象,这完全违背了类型安全规则,必然触发异常。

正确解决方案:用JSON序列化存储对象列表

SharedPreferences仅支持存储基本类型和字符串,因此我们需要把List<tcmb>转成JSON字符串来存储,读取时再将JSON转回对象列表。推荐用Google的Gson库来简化这个序列化/反序列化过程。

步骤1:添加Gson依赖

在模块级别的build.gradle中添加依赖(使用最新版本即可):

dependencies {
    implementation 'com.google.code.gson:gson:2.10.1'
}

步骤2:修改setList方法

将对象列表转成JSON字符串后存储:

public static void setList(Context context, List<tcmb> mValuesList) {
    Gson gson = new Gson();
    String jsonString = gson.toJson(mValuesList); // 将对象列表转为JSON字符串
    
    SharedPreferences values = context.getSharedPreferences("dd", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = values.edit();
    editor.putString("ss", jsonString);
    editor.apply();
}

注:把参数从Application改为Context,这样Activity、Fragment都能传入,兼容性更强。

步骤3:修改getList方法

读取JSON字符串并解析回List<tcmb>:

public static List<tcmb> getList(Context context) {
    SharedPreferences values = context.getSharedPreferences("dd", Context.MODE_PRIVATE);
    String jsonString = values.getString("ss", "");
    
    if (jsonString.isEmpty()) {
        return new ArrayList<>(); // 返回空列表,避免后续空指针异常
    }
    
    Gson gson = new Gson();
    // 用TypeToken指定泛型类型,确保Gson能正确解析为List<tcmb>
    Type listType = new TypeToken<List<tcmb>>() {}.getType();
    return gson.fromJson(jsonString, listType);
}

这里移除了错误的强转逻辑,直接通过Gson生成正确的对象列表。

步骤4:修正调用处的小问题

  • 启动页splashTask中,将SharedPreferenceValues.setValuesList改为setList(匹配方法名):
    SharedPreferenceValues.setList(getApplication(), mtcmbList);
    
  • Fragment的DownloadXmlTask中,调用getList时传入getContext()即可:
    return SharedPreferenceValues.getList(getContext());
    

额外注意事项

  1. 确保tcmb类是public访问权限,且字段可被Gson访问(要么是public修饰,要么提供getter/setter方法),否则序列化/反序列化会失败。
  2. 如果tcmb类包含嵌套对象,也要保证嵌套类符合序列化要求。
  3. 原代码中getList方法存在变量名错误:dovizList = (List)itemsList;里的itemsList应为itemList,不过使用Gson方案后这段代码已被替代,无需再关注。

完成以上修改后,你存储的是真正的对象数据,读取时能得到正确的List<tcmb>,类型转换异常就会彻底消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:08:43