欢迎光临
感受代码之美

Google Gson报错:java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to解决办法

Google Gson报错:java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to解决办法

错误信息:

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to lc.jw.lgzr.sritemsstandard.data.SrItemsStandard

产生异常代码:

Gson gson = new Gson();
List<SrItemsStandard> stdList = gson.fromJson(standardArray, List.class);
srItemsService.save(srItems);
//保存标准
for(SrItemsStandard srItemsStandard:stdList){
    srItemsStandard.setSrItemsId(srItems.getSrItemId());
    srItemsStandardService.save(srItemsStandard);
}

错误原因:

当你调用 toJson(obj) 的时候,Gson 会调用 obj.getClass() 来获取信息。同样的,你可以在 fromJson(json, MyClass.class) 方法中传入 MyClass.class 对象。如果该对象是一个非泛型类型,那么一切都会正常运行。然而,如果对象是一个泛型类型,由于 Java 的类型擦除机制,泛型类型信息会被丢失。下面用一个例子来阐明这个观点:

class Foo<T> {
  T value;
}
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); //  不会正确地序列化 foo.value 字段

gson.fromJson(json, foo.getClass()); // 反序列化 foo.value 失败

上面的代码希望得到 value 的类型: Bar,然而运行的时候是失败的。因为 Gson 调用 list.getClass() 来得到类型信息,而这个方法在上面的代码中会得到一个原始类,Foo.class。也就是说 Gson 没办法知道这是一个 Foo 类型的对象,而不仅仅是 Foo 类型的对象。

你可以通过为通用类型指定正确的参数化类型来解决此问题。你可以通过使用 TypeToken 类来做到这一点。

Type fooType = new TypeToken<Foo<Bar>>() {}.getType();
gson.toJson(foo, fooType);

gson.fromJson(json, fooType);

上面用于获取 fooType 类型的方法实际上定义了一个匿名局部内部类,它包含一个方法 getType(),该方法返回有所的参数类型。

修改后代码:

Gson gson = new Gson();
Type srItemsStandardType = new TypeToken<List<SrItemsStandard>>() {
}.getType();
List<SrItemsStandard> stdList = gson.fromJson(standardArray, srItemsStandardType);
srItemsService.save(srItems);
//保存标准
for (SrItemsStandard srItemsStandard : stdList) {
    srItemsStandard.setSrItemsId(srItems.getSrItemId());
    srItemsStandardService.save(srItemsStandard);
}

参考:

  1. https://blog.csdn.net/xuanzhangran/article/details/78921878;
  2. Gson中文指南
转载请注明来源:四个空格 » Google Gson报错:java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to解决办法

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址