I have below code to deserialize the json array and it worked find. However, if I try to iterate the list, I am getting ClassCastException. If I replace generic type T with MyObj and the iteration works. But I wanted to make the deserialization code to be generic. Could you please help me how I can fix this error? Thanks in advance.
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to MyObj
json deserialization code
public static <T> List<T> mapFromJsonArray(String respInArray) {
Type listType = new TypeToken<ArrayList<T>>(){}.getType();
List<T> ret = new Gson().fromJson(respInArray, listType);
return ret;
}
error at the for loop.
List<MyObj> myObjResponse = JsonUtil.<MyObj>mapFromJsonArray(jsonResponse);
for(MyObj obj : myObjResponse){ // Class cast exception
//do something
}
You certainly need to give mapFromJsonArray
more information than this--that is unavoidable, since the binding of <T>
for each invocation is entirely erased at runtime. All your TypeToken
is doing is trying to reify information that you don't have.
But all you need to do is pass in the element type, and this will work:
public static <T> List<T> mapFromJsonArray(String respInArray, Class<T> elementClass) {
Type listType = new TypeToken<List<T>>(){}
.where(new TypeParameter<T>(){}, elementClass).getType();
return new Gson().fromJson(respInArray, listType);
}
It's not any more clunky to call than what you had:
List<MyObj> myObjResponse = mapFromJsonArray(jsonResponse, MyObj.class);
The TypeToken is a trick to acquire type information for a generic type at runtime. However by passing it a generic type parameter (T), due to type erasure what you're effectively doing is:
Type listType = new TypeToken<ArrayList<Object>>(){}.getType();
This isn't providing Gson with the necessary information it needs in order to deserialise into the list correctly, hence it does the deserialisation incorrectly.
One solution might be to pass the type token as a parameter to mapFromJsonArray :
public static <T> List<T> mapFromJsonArray(String respInArray, Type listType) {
List<T> ret = new Gson().fromJson(respInArray, listType);
return ret;
}
List<MyObj> myObjResponse = JsonUtil.<MyObj>mapFromJsonArray(
jsonResponse, new TypeToken<ArrayList<MyObj>>(){}.getType());
for(MyObj obj : myObjResponse){
//do something
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With