Gson, ClassCastException with universals

I have below code for deserializing a json array and it worked find. However, if I try to iterate over this list, I get a ClassCastException. If you replace the generic type T with MyObj, and the iteration will work. But I wanted to make the deserialization code universal. Could you help me, how can I 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; } 

in a for loop.

 List<MyObj> myObjResponse = JsonUtil.<MyObj>mapFromJsonArray(jsonResponse); for(MyObj obj : myObjResponse){ // Class cast exception //do something } 
+5
source share
2 answers

You certainly need to provide mapFromJsonArray more information than this - this is inevitable, since the <T> binding for each call is completely erased . All of your TypeToken attempts to validate information that you do not have.

But all you have 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); } 

This is no more difficult call than yours:

 List<MyObj> myObjResponse = mapFromJsonArray(jsonResponse, MyObj.class); 
+2
source

TypeToken is a trick for getting type information for a generic type at runtime. However, passing it a generic type parameter (T), because of the erasure of the type, what you are doing is efficient:

 Type listType = new TypeToken<ArrayList<Object>>(){}.getType(); 

This does not give Gson the necessary information necessary to deserialize the list correctly, so it does not properly deserialize.

One solution could be to pass a type marker 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 } 
+1
source

Source: https://habr.com/ru/post/1200858/


All Articles