【问题标题】:Java, Gson, Lists and GenericsJava、Gson、列表和泛型
【发布时间】:2016-08-15 16:53:53
【问题描述】:

只要不涉及列表,我已经看到了这个问题的一些解决方案,所以我靠运气看看是否可以做点什么。

我希望使用泛型分解一些大量重复的代码。我遇到了可能与类型擦除有关的麻烦。首先,这是一个重复代码的示例:

    private void readsFoo() throws Exception {
    JsonArray jsonArray = getJsonArray(foo_field);

    Type listType = new TypeToken<List<Foo>>() {
    }.getType();

    List<Foo> fooList= gson.fromJson(jsonArray, listType);

    for (Foo foo : fooList) {
        .....
    }
}

private void readsGoo() throws Exception {
    JsonArray jsonArray = getJsonArray(goo_field);

    Type listType = new TypeToken<List<Goo>>() {
    }.getType();

    List<Goo> gooList= gson.fromJson(jsonArray, listType);

    for (Goo goo : gooList) {
        .....
    }
}

现在,这是我自己编写的代码:

private void readsFoo() throws Exception {
    JsonArray jsonArray = getJsonArray(foo_field);
    List<Foo> fooList = getElementsList(jsonArray);

    for (Foo foo: fooList ) {
       .....
    }
}

private <T> List<T> getElementsList(JsonArray iArray)
{
    Type listType = new TypeToken<List<T>>() {}.getType();
    validateJsonElement(listType, "In getElementsList: Unable to find field TypeTokens");

    List<T> list = gson.fromJson(iArray, listType);
    validateJsonElement(list, "In getElementsList: Unable to find list from Json");

    return list;
}

在运行时,我收到以下错误:java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to ....json.Foo

有没有办法解决这个问题?因为坦率地说,我讨厌不可重用的代码。 谢谢!

【问题讨论】:

  • 您是否调试过您的代码(两个版本)以查看两个变体中的 listType 是什么?你能发布堆栈跟踪吗?

标签: java list generics gson


【解决方案1】:

基本上,TypeToken 不能使用泛型类型。您可以将其作为参数传递:

private void readsFoo() throws Exception {
    JsonArray jsonArray = getJsonArray(foo_field);
    List<Foo> fooList = getElementsList(jsonArray, new TypeToken<List<Foo>>(){});

    for (Foo foo: fooList ) {
       .....
    }
}

private <T> List<T> getElementsList(JsonArray iArray, TypeToken<List<T>> tt)
{
    Type listType = tt.getType();
    validateJsonElement(listType, "In getElementsList: Unable to find field TypeTokens");

    List<T> list = gson.fromJson(iArray, listType);
    validateJsonElement(list, "In getElementsList: Unable to find list from Json");

    return list;
}

你对擦除的看法是正确的。由于T 被删除,您创建的TypeToken 将保存类型List&lt;T&gt; 而不是List&lt;Foo&gt;,它不保存任何信息。

【讨论】:

  • 谢谢你的建议,我马上试试
猜你喜欢
  • 1970-01-01
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
相关资源
最近更新 更多