Java保存ArrayList<Dot>到SharedPreferences触发IllegalArgumentException求助
这个问题我之前踩过坑,本质原因很明确:SharedPreferences本身不支持直接存储自定义对象的集合——它只能处理基本数据类型、String以及StringSet这类简单结构。当你尝试存入带自定义泛型的ArrayList<Dot>时,SharedPreferences无法完成对象的序列化操作,因此抛出IllegalArgumentException。而去掉泛型后错误消失,只是编译器放松了类型检查的“假象”,你并没有真正把Dot对象正确存储进去,后续读取时肯定会出问题。
下面是靠谱的解决方案,用JSON序列化来处理自定义对象集合:
步骤1:确保Dot类是标准POJO
Gson这类JSON库可以直接处理普通的Java对象,不需要强制实现Serializable,只要字段能被访问到(要么是public,要么有getter/setter)就行,另外记得加无参构造方法(反序列化时需要):
public class Dot { private int x; private int y; // 无参构造方法(Gson反序列化必备) public Dot() {} // 带参构造方法 public Dot(int x, int y) { this.x = x; this.y = y; } // Getter和Setter public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } }
步骤2:用Gson将ArrayList转为JSON字符串存储
我们把自定义对象集合转成SharedPreferences能识别的String类型,再存入:
// 获取SharedPreferences实例 SharedPreferences sharedPref = getSharedPreferences("DotPrefs", Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); // 构造你的Dot列表 ArrayList<Dot> dotList = new ArrayList<>(); dotList.add(new Dot(15, 25)); dotList.add(new Dot(35, 45)); // 序列化列表为JSON字符串 Gson gson = new Gson(); String dotJson = gson.toJson(dotList); // 存入SharedPreferences editor.putString("saved_dots", dotJson); editor.apply(); // 异步保存,比同步的commit()更推荐
步骤3:从SharedPreferences读取并还原列表
读取时把JSON字符串转回ArrayList<Dot>,这里要注意用TypeToken解决Java泛型擦除的问题:
SharedPreferences sharedPref = getSharedPreferences("DotPrefs", Context.MODE_PRIVATE); String savedDotJson = sharedPref.getString("saved_dots", null); if (savedDotJson != null) { Gson gson = new Gson(); // 用TypeToken获取泛型类型,避免泛型擦除导致的类型转换错误 Type dotListType = new TypeToken<ArrayList<Dot>>() {}.getType(); ArrayList<Dot> restoredDotList = gson.fromJson(savedDotJson, dotListType); // 现在restoredDotList就是你之前保存的列表,可以正常使用 }
步骤4:添加Gson依赖
如果你的项目还没引入Gson,在Module级别的build.gradle里添加依赖(建议用最新版本):
dependencies { implementation 'com.google.code.gson:gson:2.10.1' }
最后再提醒一句:去掉泛型只是绕过了编译检查,SharedPreferences根本没能力存储自定义对象,所以这个方法完全不可取。用JSON序列化才是正确的思路,既能保证数据正确存储,又能保留泛型类型的安全性。
内容的提问来源于stack exchange,提问作者Chinaedu Onwukwe
相关产品推荐
相关产品推荐

