如何解决ClassCastException:String无法转为tcmb对象异常
解决ClassCastException:String无法转成tcmb对象的问题
这个异常的核心原因非常明确:你存储到SharedPreferences的是tcmb对象的字符串表示(默认toString()方法的输出),但读取时却试图把这些普通字符串直接强转成tcmb对象——String和tcmb是完全不同的类型,JVM根本无法完成这个转换,自然抛出ClassCastException。
问题根源拆解
setList存储逻辑错误:
你用valuesBuilder.append(s);拼接的是tcmb对象的默认toString()结果(通常是com.example.lscodex.ddddd.Model.tcmb@xxxxxx格式),本质上只是存了一堆字符串,而非对象本身的有效数据。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());
额外注意事项
- 确保
tcmb类是public访问权限,且字段可被Gson访问(要么是public修饰,要么提供getter/setter方法),否则序列化/反序列化会失败。 - 如果
tcmb类包含嵌套对象,也要保证嵌套类符合序列化要求。 - 原代码中
getList方法存在变量名错误:dovizList = (List)itemsList;里的itemsList应为itemList,不过使用Gson方案后这段代码已被替代,无需再关注。
完成以上修改后,你存储的是真正的对象数据,读取时能得到正确的List<tcmb>,类型转换异常就会彻底消失。
内容的提问来源于stack exchange,提问作者lscodex
相关产品推荐
相关产品推荐

