2016-08-15 4 views
0

Я видел некоторое решение этой проблемы, пока списки не задействованы, поэтому я нажимаю свою удачу, чтобы узнать, можно ли что-то сделать.Java, Gson, Lists and Generics

Я ищу факторизацию некоторого тяжелого дублированного кода с использованием дженериков. У меня проблемы, которые, вероятно, связаны с типом стирания. Прежде всего, здесь приведен пример дублированного кода:

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 не может быть отброшен в ... json.Foo

Есть ли способ решить эту проблему? Потому что, честно говоря, я не ненавижу код многократного использования. Спасибо!

+0

ли вы отладки кода (обе версии), чтобы увидеть, что 'listType' в обоих вариантах? И можете ли вы опубликовать стек? – Thomas

ответ

0

В принципе, 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<T> вместо List<Foo>, который не держит никакой информации.

+0

Спасибо за этот совет, я попробую его сразу – Zangdar