使用参数创建模板类型的新对象

时间:2015-07-20 15:01:57

标签: java

我在java中编写了一些JSON解析代码,我有几种方法,它们之间的唯一区别是它们是返回JSONObject还是JSONArray。我试图从这个出发:

  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继承而没有通用接口:(

1 个答案:

答案 0 :(得分: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,而是提供相应构造函数的所有内容都可以。