来自Json的Gson反编译generics

在使用Android应用程序时,我遇到了一个问题,当我想制作一个终极通用方法来发送HTTP请求(使用loopj)并反序列化它们(使用Gson)。

正如您在使用gson.fromJson可能知道的gson.fromJson您不能这样做:

 gson.fromJson(responseBody, new TypeToken() {}.getType()); 

要么

 gson.fromJson(responseBody, new TypeToken<ArrayList>() {}.getType()) 

您已经作为T传递的实际对象(或LinkedTreeMap情况下的实际对象列表)代替了LinkedTreeMap对象(或LinkedTreeMap对象列表)。

如果您仍想要反序列化generics类型对象(-s),请参阅下面的答案。

+ Bonus:loopj + gson的终极通用解决方案

感谢这些post的作者和评论者:

http://blog.xebia.com/2009/02/07/acessing-generic-types-at-runtime-in-java/

如何获得通用接口的具体类型

Java Type Generic作为GSON的参数

将JSON对象反序列化为generics类型java对象

首先,我们需要获得generics类型T的实际类。

我们可以通过传递类本身( Class cl )或从具有generics类型的对象( SomeObject someObjectWithGenericType )获取类来实现。 我将在示例中使用第二种情况。

然后我们需要创建一个Element类的特殊对象,它将告诉Gson用于反序列化的类。

 public  T getObject(String json, SomeObject someObjectWithGenericType) { Class cl = getTypeClassOfObject(someObjWithGenericType); T object = gson.fromJson(json, new Element(cl)); return object; } private Class getTypeClassOfObject(Object obj) { return (Class) ((ParameterizedType) obj.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } private class Element implements ParameterizedType { private Class cl; public Element(Class cl) { this.cl = cl; } public Type[] getActualTypeArguments() { return new Type[] {cl}; } public Type getRawType() { return cl; } public Type getOwnerType() { return null; } } 

如果您的SomeObject是一个接口(可能是回调,稍后您将在loopj示例中看到),您可以使用此方法而不是getTypeClassOfObject

 private Class getTypeClassOfInterfaceObject(Object obj) { return (Class) ((ParameterizedType) obj.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; } 

将JSON数组反序列化为generics类型java对象的列表

同样的想法,但我们有一个不同的特殊类来帮助Gson进行反序列化:

 public  List getList(String json, SomeObject someObjectWithGenericType) { Class cl = getTypeClassOfObject(someObjWithGenericType); List list = gson.fromJson(json, new ListWithElements(cl)); return list; } private class ListWithElements implements ParameterizedType { private Class elementsClass; public ListWithElements(Class elementsClass) { this.elementsClass = elementsClass; } public Type[] getActualTypeArguments() { return new Type[] {elementsClass}; } public Type getRawType() { return List.class; } public Type getOwnerType() { return null; } } 

奖金

正如您将在这里看到的, someObjectWithGenericType将成为具有generics类型T的回调。 即使我使用loopj,我确信任何其他异步http客户端都可以用来实现相同的结果。

loopj + Gson with generics:object

 public  void getObject(String url, HashMap paramsMap, final GetObjectCallback callback) { RequestParams params = convertParams(paramsMap); client.get(url, params, new TextHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, String responseBody) { try { Class cl = getTypeClassOfInterfaceObject(callback); T object = gson.fromJson(responseBody, new Element(cl)); if (object != null) { callback.onSuccess(object); } else { callback.onFailure(); } } catch (Exception e) { e.printStackTrace(); callback.onFailure(); } } @Override public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable error) { error.printStackTrace(); callback.onFailure(); } }); } private RequestParams convertParams(HashMap paramsMap) { RequestParams params = new RequestParams(); if (paramsMap != null) { for (String key : paramsMap.keySet()) { params.put(key, paramsMap.get(key)); } } return params; } public interface GetObjectCallback { void onSuccess(T item); void onFailure(); } 

loopj + Gson with generics:list

 public  void getList(String url, HashMap paramsMap, final GetListCallback callback) { RequestParams params = convertParams(paramsMap); client.get(url, params, new TextHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, String responseBody) { try { Class cl = getTypeClassOfInterfaceObject(callback); List list = gson.fromJson(responseBody, new ListWithElements(cl)); if (list != null) { callback.onSuccess(list); } else { callback.onFailure(); } } catch (Exception e) { e.printStackTrace(); callback.onFailure(); } } @Override public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable error) { error.printStackTrace(); callback.onFailure(); } }); } public interface GetListCallback { void onSuccess(List list); void onFailure(); } 

用法:对象

 api.getObject(URL, paramsMap, new GetObjectCallback() { @Override public void onSuccess(NewsItem item) { // do something } @Override public void onFailure() { // do something } }); 

用法:清单

 api.getList(URL, paramsMap, new GetListCallback() { @Override public void onSuccess(List list) { // do something } @Override public void onFailure() { // do something } }); 

任何改进都非常受欢迎!