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

Java保存ArrayList<Dot>到SharedPreferences触发IllegalArgumentException求助

解决SharedPreferences存储ArrayList时的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:28:43