使用gson进行序列化/反序列化时无法强制转换为子类

rkttyhzu  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(305)

我定义了一个带有ArrayList变量的Record类,它存储了Base类的示例列表(这些示例实际上是Sub类的示例)。
样本代码

  1. public class Record {
  2. private ArrayList<Base> list;
  3. public void Record() {
  4. list = new ArrayList<>();
  5. }
  6. public add(Base instance) {
  7. list.add(instance) // instance is of Sub class
  8. }
  9. private class Sub extends Base {}
  10. }

我使用gson库将其序列化为共享首选项

  1. SharedPreferences.Editor editor = sharedPreferences.edit();
  2. Gson gson = new Gson();
  3. editor.putString(KEY, gson.toJson(record)); // an Arraylist of Record instances
  4. editor.commit();

但当将其反序列化回Record示例的ArrayList,并试图通过将其强制转换为Sub类来从列表中的示例调用Sub类的方法时,我收到了类似“java.lang.ClassCastException:无法将类Base强制转换为类Sub”

  1. Gson gson = new Gson();
  2. Type type = new TypeToken<TreeMap<String, Record>>() {}.getType();
  3. TreeMap<String, Record> records = gson.fromJson(sharedPreferences.getString(RECORDS_KEY, null), type);
  4. // trying to call the method from the subclass
  5. ((Sub)records.get("a").list[0]).methodFromSub();
taor4pac

taor4pac1#

Gson接收的java.lang.reflect.TypeTreeMap<String, Record>,而Record中的字段list类型是ArrayList<Base>。因此,Gson将list反序列化为ArrayList<Base>NOTArrayList<Sub>。要指定list类型以让Gson知道反序列化SubBase,请尝试以下代码:

  1. class Base {
  2. public String base;
  3. }
  4. class Record<T extends Base> {
  5. public ArrayList<T> list;
  6. public void Record() {
  7. list = new ArrayList<>();
  8. }
  9. public void add(T instance) {
  10. list.add(instance); // instance is of Sub class
  11. }
  12. class Sub extends Base {
  13. public String sub;
  14. public String getBaseAndStub() {
  15. return (base != null ? base : "") + (sub != null ? sub : "");
  16. }
  17. }
  18. }

我已经测试了上面代码,它工作正常:

  1. public void test() {
  2. String json = "{\n" +
  3. " \"haha\": {\n" +
  4. " \"list\": [\n" +
  5. " {\n" +
  6. " \"sub\": \"sub\",\n" +
  7. " \"base\": \"base\"\n" +
  8. " }\n" +
  9. " ]\n" +
  10. " }\n" +
  11. "}";
  12. Gson gson = new Gson();
  13. Type type = new TypeToken<TreeMap<String, Record<Record.Sub>>>() {}.getType();
  14. TreeMap<String, Record<Record.Sub>> map = gson.fromJson(json, type);
  15. System.out.println(map.get("haha").list.get(0).getBaseAndStub());
  16. // Output: basesub
  17. }
展开查看全部

相关问题