2015-06-21 122 views
0

我是新來的java泛型,下面是代碼,已經創建了一個混淆,我把泛型類作爲參數傳遞給方法。 我卻造成讓我用排槍庫來處理服務器calls.Below的Android項目是代碼如何將類作爲泛型傳遞?

高級連接的Util:該類返回JacksonRequest對象

public class AdvancedConnectionUtil<T> { 

private String requestType; 
private ServerListener listener; 

public AdvancedConnectionUtil(String requestType , ServerListener<T> listener){ 

    this.listener = listener; 
    this.requestType = requestType; 
} 

public JacksonRequest getRequest(){ 

      //This gives compile error while while passing DataList.class in the argument 
      return new JacksonRequest<T>(Request.Method.GET, HttpRequestConstant.JACKSON_FETCH, null ,DataList.class, new Response.Listener<T>() { 
       @Override 
       public void onResponse(T response) { 
        listener.onDataReceived(response); 

       } 
      }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        listener.onErrorReceived(error.getMessage()); 
       } 
      }); 
    } 


public interface ServerListener<T> { 

    public void onDataReceived(T data); 

    public void onErrorReceived(String errorMsg); 

} 

} 

定製JacksonRequest類:該類手柄服務器調用和成功回調

public class JacksonRequest<T> extends JsonRequest<T> { 

private Class<T> responseType; 

/** 
* Creates a new request. 
* @param method  the HTTP method to use 
* @param url   URL to fetch the JSON from 
* @param requestData A {@link Object} to post and convert into json as the request. Null is allowed and indicates no parameters will be posted along with request. 
* @param responseType 
* @param listener  Listener to receive the JSON response 
* @param errorListener Error listener, or null to ignore errors. 
*/ 
public JacksonRequest(int method, String url, Object requestData, Class<T> responseType, Response.Listener<T> listener, Response.ErrorListener errorListener) { 
    super(method, url, (requestData == null) ? null : Mapper.string(requestData), listener, errorListener); 
    this.responseType = responseType; 
} 


@Override 
public Map<String, String> getHeaders() throws AuthFailureError { 
    return super.getHeaders(); 
} 

@Override 
protected Response<T> parseNetworkResponse(NetworkResponse response) { 

    try { 
     String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 
     return Response.success(Mapper.objectOrThrow(json, responseType), HttpHeaderParser.parseCacheHeaders(response)); 
    } catch (Exception e) { 
     return Response.error(new ParseError(e)); 
    } 
} 

}

這裏是我的行爲創建一個請求並將其傳遞給其他方法ivity類,使一臺服務器調用

public class CustomJacksonRequestActivity extends SuperActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    showProgressBar(); 

    JacksonRequest jacksonRequest = new AdvancedConnectionUtil<DataList>(null, httpListener).getRequest(); 

    //This commented code works fine when i create a request this way 
    /* JacksonRequest<DataList> jacksonRequest = new JacksonRequest<DataList>(Request.Method.GET, HttpRequestConstant.JACKSON_FETCH, null, DataList.class, new Response.Listener<DataList>() { 
     @Override 
     public void onResponse(DataList response) { 
      hideProgressBar(); 
      Log.e("ANSH", "onResponse : " + response.getPicture()); 
      // fillListWithIndex(response); 

     } 
    }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      hideProgressBar(); 
      Log.e("ANSH", "onErrorResponse : " + error.getLocalizedMessage()); 
     } 
    });*/ 

    onExecute(jacksonRequest); 
} 

@Override 
protected void internetAvailable() { 

} 


@Override 
public void setTitle(CharSequence title) { 
    super.setTitle("CustomJacksonActivity"); 
} 
private AdvancedConnectionUtil.ServerListener httpListener = new AdvancedConnectionUtil.ServerListener<DataList>() { 
    @Override 
    public void onDataReceived(DataList data) { 
     Log.e("ANSH", "onResponse : " + data.getPicture()); 
    } 

    @Override 
    public void onErrorReceived(String errorMsg) { 
     Log.e("ANSH", "onResponse : " + errorMsg); 
    } 
}; 

現在的問題是我不能夠通過DataList.class(這是響應模型類)作爲參數JacksonRequest Class的構造函數在AdvancedConnectionUtil類的getRequest方法內,但我可以在活動中創建請求對象(請參閱活動中的註釋代碼)時執行此操作。 我如何將DataList.class傳遞給JacsonRequest的構造函數?

更新的代碼是git的樞紐,現在 github link to the project

回答

0

你的代碼是一個有點混亂(你可以用一個簡單的例子做),但我給它一個鏡頭...

JacksonRequest類需要一個泛型類型參數<T>和第4個構造函數參數的類型引用此類型:, Class<T> responseType,。這意味着當JacksonRequest的實例被實例化(其中T是一個真實類型)時,傳遞的第四個參數必須保證爲T.class

當你調用構造函數...

return new JacksonRequest<T>(Request.Method.GET, blah, null ,DataList.class, ... 

...你是一個泛型類型參數<T>調用它。編譯器必須始終能夠將泛型類型參數與泛型類型參數進行匹配,但使用第四個參數要求它將TDataClass匹配。由於編譯器不知道什麼是T(或者更準確地說,它不能保證當它被實例化時,T實際上是DataClass),它會給出一個錯誤。

一般來說,您不能混用泛型類型參數和實型值 - 您必須始終選擇其中一種。有些選項允許你指定一個泛型類型參數將從一個類派生或實現一個接口(<T super DataClass><T extends DataClass>,但這裏有一點需要解釋。

+0

你的回答是有道理的me.But什麼是做到這一點的方式事情。我唯一的來自AdvancedConnectionUtil類的動機是創建請求對象並將其返回給Activity類。現在我可以怎樣將響應類(即DataList.class)傳遞給JacksonRequest構造函數?任何想法? – anshul

+0

如果您將T.class而不是DataList.class作爲第四個參數傳遞,會發生什麼? – adelphus

+0

我試圖T.class但它提請紅線,並說 – anshul

0

與您的代碼的問題是: 你JacksonRequest<T>宣佈採取listener必須參數在同類型與AdvancedConnectionUtil<T>.getRequest(...)responseType

但是,不能保證所創建的JacksonRequest將符合上述要求。因爲你總是可以寫代碼,如:

new AdvancedConnectionUtil<String> (null, httpListener).getRequest(); 

所以你傳入的JacksonRequest構造函數的參數將是DataList.class(的Class<DataList>型)和類型Listener<String>

listener可悲的是有沒有辦法在Java中執行T.class,雖然這確實感覺像你所需要的。通常在這樣的情況下,我們將宣佈AdvancedConnectionUtil爲:

class AdvancedConnectionUtil<T> { 
    private final Class<T> responseType; 
    private final ServerListener<T> serverListener; 
    private final String requestType; 

    public AdvancedConnectionUtil (String requestType , Class<T> responseType, ServerListener<T> listener) { 
    this.requestType = requestType; 
    this.responseType = responseType; 
    this.serverListener = listener; 
    } 

    public JacksonRequest<T> getRequest(){ 
     return new JacksonRequest<T>(0, "", null ,responseType, new Response.Listener<T>(){ 
     ...   
     } 
    } 

您需要根據您的Class<T>的responseType進入AdvancedConnectionUtil,並將其作爲一個成員字段。這樣,AdvancedConnectionUtil實例在創建時嚴格限於提供JacksonRequest限定爲特定的響應類型。

理論上你可以聲明你調用getRequest方法getRequest(Class<T> responseType)。但是,你的AdvancedConnectionUtil似乎並沒有獲得來自

+0

耶在最後一個「無法從類型變量選擇」我可以這樣做:(謝謝無論如何 – anshul

相關問題