【问题标题】:java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to modeljava.lang.ClassCastException:com.google.gson.internal.LinkedTreeMap 无法转换为模型
【发布时间】:2016-07-26 00:47:22
【问题描述】:

查看 Stackoverflow 问题后,我找不到任何解决此问题的解决方案。

我正在尝试使用 GSON 并实现了这样的通用方法:

public <T> List<T> deserializeList(String json) {
    Gson gson = new Gson();
    Type type = (new TypeToken<List<T>>() {}).getType();
    return  gson.fromJson(json, type);
}

通过这个方法调用这个方法:

parser.<Quote>deserializeList(result)

但是我得到的结果是这样的:

当我试图访问一个对象时,我得到了这个错误:

 java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to model.Quote

JSON 字符串为:

[
    {
      "id": 269861,
      "quote": "People living deeply have no fear of death.",
      "author": "Anais Nin",
      "genre": "life",
      "tag": null,
      "createdAt": "2016-04-16T13:13:36.928Z",
      "updatedAt": "2016-04-16T13:13:36.928Z"
    }
]

【问题讨论】:

  • 我不认为你应该使用类型参数调用该方法
  • @cricket_007 有无无关紧要 - parser.deserializeList(result)
  • 我就是这么想的。现在,类定义中的T 是什么?第二个问题,你可以使用 Retrofit 吗?
  • @cricket_007 类定义中没有 T,因为它是通用方法。不,我还没有使用 Http;静态 JSON 在我需要解析的原始资源中。它一直在工作,直到我把它作为一种通用方法。所以我只是想知道它是如何影响的。如果我用特定类的类型对 TypeToken 进行硬编码,那么它工作得很好。但是我对我拥有的所有不同的 json 重复相同的操作。
  • 为什么不给方法一个Type参数而不是尝试使用泛型?

标签: java json gson deserialization


【解决方案1】:

我认为您可以编写这样的方法来显式提供Type

public <T> List<T> deserializeList(String json, Type type) {
    Gson gson = new Gson();
    return  gson.fromJson(json, type);
}

不过,绕过(new TypeToken&lt;List&lt;Model&gt;&gt;() {}).getType(); 看起来有点乱。

我对类型擦除不太熟悉,但我敢打赌这与问题有关。

【讨论】:

    【解决方案2】:

    以上解析方式错误,修改如下代码:

    public static <T> List<T> getObjectList(String jsonString,Class<T> cls){
        List<T> list = new ArrayList<T>();
        try {
            Gson gson = new Gson();
            JsonArray arry = new JsonParser().parse(jsonString).getAsJsonArray();
            for (JsonElement jsonElement : arry) {
                list.add(gson.fromJson(jsonElement, cls));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
    

    【讨论】:

      【解决方案3】:

      在 Kotlin 中,您可以定义一个具体化的扩展函数,例如:

      internal inline fun <reified T> Gson.fromJson(json: String) =
          fromJson<T>(json, object : TypeToken<T>() {}.type)
      

      然后像这样使用它:

      val resultJson = "{...}"
      val quotesList: List<Quote> = gson.fromJson(resultJson)
      

      说明:在运行时,所有泛型类型都被擦除(编译器可以创建完全正确的代码,而无需在运行时保留泛型类型)。但是,如果您将一个类型声明为 reified,您就可以在运行时在函数中使用该类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-03
        • 2018-06-10
        • 2020-09-20
        • 1970-01-01
        • 2016-11-21
        • 1970-01-01
        • 2021-02-13
        • 2021-12-27
        相关资源
        最近更新 更多