java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap无法转换为model

5

在查看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)

然而我得到的结果是这样的:

enter image description here

当我试图访问一个对象时,我会得到这个错误:
 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"
    }
]

我认为你不应该使用类型参数来调用该方法。 - OneCricketeer
@cricket_007 有或没有都无所谓——parser.deserializeList(result) - codebased
这正是我所想的。现在,在类定义中,T代表什么?另外一个问题,你可能正在使用Retrofit吗? - OneCricketeer
@cricket_007 类定义中没有T,因为它是一个通用方法。不,我还没有使用Http;一个静态的JSON在原始资源中,我需要解析它。直到我将其作为通用方法后,它一直在工作。所以我想知道它是如何受影响的。如果我硬编码TypeToken与特定类的类型,那么它就可以正常工作。但是这样我就要为我拥有的所有不同的json重复相同的操作。 - codebased
1
为什么不给该方法一个“类型”参数,而不是尝试使用泛型? - OneCricketeer
显示剩余2条评论
3个回答

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;
}

2
我觉得你可以这样编写该方法,以明确地提供 Type
public <T> List<T> deserializeList(String json, Type type) {
    Gson gson = new Gson();
    return  gson.fromJson(json, type);
}

尽管如此,传递 (new TypeToken<List<Model>>() {}).getType(); 看起来有点凌乱。

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


2
在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,则可以在函数内在运行时使用该类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接