Deserializar los tipos generics con GSON

Tengo algunos problemas con la implementación de Deserialización Json en mi aplicación Android (con la biblioteca Gson)

He hecho una clase como esta

public class MyJson{ public List posts; } 

Y la llamada de deserialización es:

 public class JsonDownloader extends AsyncTask<Void, Void, MyJson> { ... protected MyJson doInBackground(Void... params) { ... Reader reader = new InputStreamReader(content); GsonBuilder gson = new GsonBuilder(); Type collectionType = new TypeToken<MyJson>() {}.getType(); result = gson.create().fromJson(reader, collectionType); ... } } 

El problema es que result.posts list after call contiene una matriz de objetos LinkedTreeMap (con los valores correctos, por lo que el problema es la deserialización) en lugar de los objetos MyJson. Cuando uso MyObject en lugar de T, todo funciona bien y MyObject es correcto.

Entonces, ¿hay alguna forma de implementar la llamada de deserialización sin crear un deserializador personalizado?

¿Has probado?

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

EDITAR

Después de leer esta publicación, parece que el uso de Type es correcto. Creo que su problema es el uso de T Debe recordar que con Java hay borrado de tipo. Esto significa que en el tiempo de ejecución todas las instancias de T se reemplazan por Object . Por lo tanto, en tiempo de ejecución, lo que está pasando GSON es realmente MyJson . Si intentaste esto con una clase concreta en lugar de , creo que funcionaría.

Google Gson: ¿deserializar el objeto de la lista ? (tipo genérico)

Debe especificar el tipo de T en el momento de la deserialización. ¿Cómo se crearía su List de posts si Gson no sabía qué Type crear una instancia? No puede permanecer T para siempre. Por lo tanto, proporcionaría el tipo T como parámetro de Class .

Suponiendo ahora que el tipo de posts era String , deserializaría MyJson como (también he agregado un parámetro String json para simplificar, leería de su reader como antes):

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

Del mismo modo, para deserializar un MyJson de objetos Boolean

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

Supuse que MyJson para que mis ejemplos sean tan

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

Entonces, si estabas buscando deserializar una List invocarías el método como

 // assuming no Void parameters were required MyJson myJson = doInBackground(MyObject.class); 

Así que la respuesta anterior no funcionó para mí, después de la prueba y error, así es como terminó mi código:

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

La parte importante aquí es la firma del método, que incluye ‘‘ a la izquierda.

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

Al llamar a Gson, el método recibe el TypeToken del objeto genérico.

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

Y finalmente el TypeToken puede usar MyDTO, o incluso un objeto simple, simplemente MyDTO.