Deserializing Generic Types with GSON Deserializing Generic Types with GSON json json

Deserializing Generic Types with GSON


You have to specify the type of T at the time of deserialization. How would your List of posts get created if Gson didn't know what Type to instantiate? It can't stay T forever. So, you would provide the type T as a Class parameter.

Now assuming, the type of posts was String you would deserialize MyJson<String> as (I've also added a String json parameter for simplicity; you would read from your reader as before):

doInBackground(String.class, "{posts: [\"article 1\", \"article 2\"]}");protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) {    GsonBuilder gson = new GsonBuilder();    Type collectionType = new TypeToken<MyJson<T>>(){}.getType();    MyJson<T> myJson = gson.create().fromJson(json, collectionType);    System.out.println(myJson.getPosts()); // ["article 1", "article 2"]    return myJson;}

Similarly, to deserialize a MyJson of Boolean objects

doInBackground(Boolean.class, "{posts: [true, false]}");protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) {    GsonBuilder gson = new GsonBuilder();    Type collectionType = new TypeToken<MyJson<T>>(){}.getType();    MyJson<T> myJson = gson.create().fromJson(json, collectionType);    System.out.println(myJson.getPosts()); // [true, false]    return myJson;}

I've assumed MyJson<T> for my examples to be as

public class MyJson<T> {    public List<T> posts;    public List<T> getPosts() {        return posts;    }}

So, if you were looking for to deserialize a List<MyObject> you would invoke the method as

// assuming no Void parameters were requiredMyJson<MyObject> myJson = doInBackground(MyObject.class);


Have you tried?

gson.create().fromJson(reader, MyJson.class);

EDIT

After reading this post it seems that you use of Type is correct. I believe your issue is the use of T. You must remember that with Java there is type-erasure. This means that at runtime all instances of T are replaced with Object. Therefore at runtime what you are passing GSON is really MyJson<Object>. If you tried this with a concrete class in place of <T> I believe it would work.

Google Gson - deserialize list<class> object? (generic type)


So the above answer didn't work for me, after trial and error that's how my code ended:

public class AbstractListResponse<T> {    private List<T> result;    public List<T> getResult() {        return this.result;    }}

The important part here is the method signature, including the '< T >' on the left.

protected <T> AbstractListResponse<T> parseAbstractResponse(String json, TypeToken type) {    return new GsonBuilder()            .create()            .fromJson(json, type.getType());}

When calling Gson, the method receives the TypeToken of the generic object.

TypeToken<AbstractListResponse<MyDTO>> typeToken = new TypeToken<AbstractListResponse<MyDTO>>() {};AbstractListResponse<MyDTO> responseBase = parseAbstractResponse(json, typeToken);

And finally the TypeToken can use MyDTO, or even a simple object, just MyDTO.