2015-07-20 32 views
1

我在java中編寫了一些JSON解析代碼,我有幾個方法,它們之間的唯一區別是它們是否返回JSONObjectJSONArray。我想從這個去:創建模板類型的新對象,參數

private JSONArray getJsonArray(String path) throws IOException { 
    HttpGet httpget = new HttpGet(path); 
    httpget.setConfig(requestConfig); 

    try (CloseableHttpClient httpClient = httpClientBuilder.build()) { 
     try (CloseableHttpResponse result = httpClient.execute(apiHost, httpget)) { 
     return new JSONArray(new JSONTokener(result.getEntity().getContent())); 
     } 
    } 
    } 

    private JSONObject getJsonObject(String path) throws IOException { 
    HttpGet httpget = new HttpGet(path); 
    httpget.setConfig(requestConfig); 

    try (CloseableHttpClient httpClient = httpClientBuilder.build()) { 
     try (CloseableHttpResponse result = httpClient.execute(apiHost, httpget)) { 
     return new JSONObject(new JSONTokener(result.getEntity().getContent())); 
     } 
    } 
    } 

這個(無效代碼):

private <T> get(String path, Class<T> type) throws IOException { 
    HttpGet httpget = new HttpGet(path); 
    httpget.setConfig(requestConfig); 

    try (CloseableHttpClient httpClient = httpClientBuilder.build()) { 
     try (CloseableHttpResponse result = httpClient.execute(apiHost, httpget)) { 
     return new T(new JSONTokener(result.getEntity().getContent())); 
     } 
    } 
    } 

如何正確初始化類型T的帶參數的新對象?我能否以某種方式將T的可能值限制爲JSONObject/JSONArray?我知道的<T extends Something>形式,但是這兩個似乎從Object沒有共同的接口:(

+0

'org.json'(我」假設你正在使用)不支持基因ric反序列化。使用更復雜的東西,如傑克遜或Gson。 –

+0

@SotiriosDelimanolis我不認爲這是一個愚蠢的問題。另一個問題基本上是「如何解析JSON」,而這是「如何創建對應於泛型參數的類的實例」,它完全獨立於JSON。 –

+0

@SotiriosDelimanolis提供的代碼只是爲了更好地說明我的觀點。 tobias_k得到了我的問題的本質。 –

回答

1

你可以使用反射來獲取並調用匹配的構造函數,如果有的話,如果沒有這樣的構造存在引發異常直繼承。

private <T> T get(String path, Class<T> type) throws IOException { 
    HttpGet httpget = new HttpGet(path); 
    httpget.setConfig(requestConfig); 

    try (CloseableHttpClient httpClient = httpClientBuilder.build()) { 
     try (CloseableHttpResponse result = httpClient.execute(apiHost, httpget)) { 
      Constructor<T> constructor = type.getConstructor(JSONTokener.class); 
      return constructor.newInstance(new JSONTokener(result.getEntity().getContent())); 
     } catch (ReflectiveOperationException e) { 
      throw new IllegalArgumentException("Provided result class does not accept JSONTokener parameter."); 
     } 
    } 
} 

注意,這是有點duck typing,即你真的不限制類型JSONObjectJSONArray而是一切提供了相應的構造是好的。

+0

謝謝,這正是我正在尋找的。考慮到我的大部分編程經驗都是用鴨子語言編寫的,我對此很滿意。我限制爲'JSONObject' /'JSONArray'的思路是爲了讓編譯器能夠推斷出T總是會有正確的構造函數,而不是限制函數被調用的方式。 –