我正在尝试使我的响应类通用。问题是它返回一个类型为com.google.gson.internal.LinkedTreeMap而不是Brewer类型的List。
启动所有这一切的功能:
List<Brewer> brewerList = null;
try {
Response<Brewer> responseHandler = new Response<Brewer>();
brewerList = responseHandler.getAll(response);
functionCallBack = Constants.FUNCTION_DB_BREWER;
list = brewerList.toArray(new Brewer[brewerList.size()]);
} catch (IOException e) {
Tools.LOG_ERROR(e);
}
这是我的回复课程:
public class Response<T> {
public List<T> getAll(JSONObject response) throws IOException {
List<T> brewerList = null;
// Map JSON to JAVA Objects
Type listResponse = new TypeToken<ListResponse<T>>() {
}.getType();
ListResponse<T> responseObject = Shared.gson.fromJson(response.toString(), listResponse);
if (responseObject != null) {
// Status, Message, Data
int status = responseObject.getStatus();
Tools.LOG_DEBUG("Response - getAll, Status: " + status);
if (responseObject.getData() != null && responseObject.getStatus() == 200) {
brewerList = responseObject.getData();
} else {
Tools.LOG_DEBUG("Couldn't find the webservices!");
}
}
return brewerList;
}
}
这是我从json
解析的数据类public class ListResponse<T> {
private int status;
private List<T> data;
public ListResponse() {
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
例外:
04-11 10:54:55.994 31660-31660/be.appmax.ktsjjt E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.ArrayStoreException: source[0] of type com.google.gson.internal.LinkedTreeMap cannot be stored in destination array of type be.appmax.ktsjjt.models.Brewer[]
at java.lang.System.arraycopy(Native Method)
at java.util.ArrayList.toArray(ArrayList.java:523)
at be.appmax.ktsjjt.database.SyncHandler.onRestTaskCompleted(SyncHandler.java:96)
at be.appmax.ktsjjt.webservices.WSBrewer$1.onSuccess(WSBrewer.java:36)
at com.loopj.android.http.JsonHttpResponseHandler$1$1.run(JsonHttpResponseHandler.java:125)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:16)
不幸的是,由于Java中的类型擦除,您无法执行您尝试执行的操作。
进行反序列化的各种库使用的TypeToken
hack试图解决这个问题,但是你不能像通常那样尝试使用泛型类型参数。 T
的类型在运行时被删除,Gson无法再确定实际类型,因此它返回Map
。
编辑添加:解决此问题的方法是传入TypeToken
而不是尝试在方法中创建它。这允许知道类型。在您的情况下,您想要返回List<T>
,但TypeToken
实际上是ListResponse<T>
。因此,您必须使用Generics获得一些创意,并使用边界推断TypeToken类型:
public <V extends ListResponse<T>> List<T> getAll(JSONObject response, TypeToken<V> token) throws IOException {
...
V responseObject =
Shared.gson.fromJson(response.toString(), token.getType());
...
}
当你打电话给你时,你需要传递TypeToken
个实例,但它会起作用。
Response<Brewer> responseHandler = new Response<Brewer>();
TypeToken<ListResponse<Brewer>> token = new TypeToken<ListResponse<Brewer>>(){};
brewerList = responseHandler.getAll(response, token);