2014-04-11 3 views
7

응답 클래스를 일반화하려고합니다. 문제는 유형이 Brewer가 아닌 com.google.gson.internal.LinkedTreeMap 유형의 List를 반환한다는 것입니다. 이 모든 시작Arraylist는 Brewer 대신 LinkedTreeMap 유형입니다.

기능 :

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) 
+1

유형 삭제로 인해 자바에서이를 수행 할 수 없기 때문에. 'T'는 알려지지 않았습니다. –

답변

14

불행히도 Java에서 유형 삭제 때문에 수행하려는 작업을 수행 할 수 없습니다.

역 직렬화를 수행하는 다양한 라이브러리에서 사용되는 TypeToken 해킹은 시도하고 있지만 일반 형식 매개 변수와 함께 사용할 수 없습니다. T의 유형은 런타임에 지워지고 Gson은 더 이상 실제 유형을 결정할 수 없으므로 ... Map을 반환합니다.

편집 할 내용 :TypeToken이 방법을 통해이를 만들려고 시도하는 것이 아닙니다. 이것은 유형을 알 수있게합니다. 까다로운 부분은 List<T>을 반환하고 싶지만 TypeToken은 실제로 ListResponse<T>입니다.

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 예를 전달해야합니다,하지만 그것은 작동합니다 : 그 때문에 당신은 제네릭과 창조적 인 비트를 얻을 경계로 TypeToken 유형을 추론해야한다.

Response<Brewer> responseHandler = new Response<Brewer>(); 
TypeToken<ListResponse<Brewer>> token = new TypeToken<ListResponse<Brewer>>(){}; 
brewerList = responseHandler.getAll(response, token); 
+0

오케이 좋아, 이렇게 할 방법이 없어? – kevingoos

+1

@Ghost 편집을 참조하십시오. 조금 창의적이어야하지만 문제가 해결 될 것이라고 생각합니다. –

+0

나를 위해 일한 덕분에 :) –