使用Gson从SharedPreferences加载数据时传入ArrayList参数失效问题
问题核心原因
- Java是值传递,你给方法参数
list直接赋值的操作只会修改方法栈里的局部引用副本,方法外的原ArrayList变量不会指向新的对象,因此外部拿不到加载后的数据 - IDE给
list加下划线是默认提示:「方法参数被重新赋值,该修改不会作用到方法外部的原变量」 - 当前方法使用了裸类型
ArrayList,没有指定泛型,存在类型安全隐患
修复方案
方案1:方法返回加载后的ArrayList(推荐)
把方法返回值从void改成ArrayList<Product>,直接返回加载好的结果,不要用参数传递接收对象,写法如下:
public ArrayList<Product> loadList(String name){ SharedPreferences sharedPreferences = getSharedPreferences(PREFS, MODE_PRIVATE); Gson gson = new Gson(); String json = sharedPreferences.getString(name, null); Type type = new TypeToken<ArrayList<Product>>() {}.getType(); ArrayList<Product> list = gson.fromJson(json, type); if(list == null){ list = new ArrayList<>(); } return list; }
调用时直接接收返回值即可:
ArrayList<Product> myProductList = loadList("你存数据用的key");
方案2:复用传入的ArrayList实例(仅适用于必须复用原有对象的场景)
如果确实需要往已有的ArrayList实例中填充数据,不要给list参数重新赋值,先清空原有内容,再把加载到的数据追加进去:
public void loadList(ArrayList<Product> list, String name){ if (list == null) { throw new IllegalArgumentException("传入的list不能为null"); } SharedPreferences sharedPreferences = getSharedPreferences(PREFS, MODE_PRIVATE); Gson gson = new Gson(); String json = sharedPreferences.getString(name, null); Type type = new TypeToken<ArrayList<Product>>() {}.getType(); ArrayList<Product> loadedList = gson.fromJson(json, type); // 清空原有数据,加入新加载的内容 list.clear(); if (loadedList != null) { list.addAll(loadedList); } }
该方案可以保证方法外的原list实例拿到加载后的数据,也不会触发IDE的参数重赋值下划线提示。
内容的提问来源于stack exchange,提问作者Mikołaj Garbula
相关产品推荐
相关产品推荐

