【问题标题】:Two identical methods with different parameter types两种具有不同参数类型的相同方法
【发布时间】:2019-04-05 15:01:17
【问题描述】:

我在 Java 中有两个几乎相同的方法。唯一的区别是它们具有不同的参数类型。它们使用泛型并返回输入参数的类型 T。我怎样才能摆脱重复的代码?这是我的两种方法。最终,他们都使用不同的类型调用 Spring restTemplate.exchange()。否则方法相同。

public <T> T send(Class<T> expectedClass) throws KenectRestClientException {
    if (this.logRequest) log.info("Making request: " + this.toString());

    HttpEntity<Object> entity = new HttpEntity<>(this.body, getTokenHeaders(this.token));
    RestTemplate restTemplate = new RestTemplate();

    String compiledUrl = UrlUtils.replacePathParamsInUrl(this.url, this.pathParams, this.uriEncode) + UrlUtils.compileRequestParamsToUrl(this.requestParams, this.uriEncode);

    Object[] incompatibleStrings = extractIncompatibleStrings(compiledUrl);

    try {
        return restTemplate.exchange(compiledUrl, this.httpMethod, entity, expectedClass, incompatibleStrings).getBody();
    } catch(RestClientResponseException e) {
        log.warning(RestClientResponseException.class.getSimpleName() +
                " url: " + url +
                " status code: " + e.getRawStatusCode() +
                " error body: " + e.getResponseBodyAsString() +
                " stacktrace: " + ExceptionUtils.getStackTrace(e));
        throw new KenectRestClientException("Failed to send request");
    } catch(ResourceAccessException e) {
        log.warning("Resource access exception " +
                " url: " + url +
                " stacktrace: " + ExceptionUtils.getStackTrace(e));
        throw new KenectRestClientException("Failed to send request");
    }
}

public <T> T send(ParameterizedTypeReference<T> parameterizedTypeReference) throws KenectRestClientException {
    if (this.logRequest) log.info("Making request: " + this.toString());

    HttpEntity<Object> entity = new HttpEntity<>(this.body, getTokenHeaders(this.token));
    RestTemplate restTemplate = new RestTemplate();

    String compiledUrl = UrlUtils.replacePathParamsInUrl(this.url, this.pathParams, this.uriEncode) + UrlUtils.compileRequestParamsToUrl(this.requestParams, this.uriEncode);

    Object[] incompatibleStrings = extractIncompatibleStrings(compiledUrl);

    try {
        return restTemplate.exchange(compiledUrl, this.httpMethod, entity, parameterizedTypeReference, incompatibleStrings).getBody();
    } catch(RestClientResponseException e) {
        log.warning(RestClientResponseException.class.getSimpleName() +
                " url: " + url +
                " status code: " + e.getRawStatusCode() +
                " error body: " + e.getResponseBodyAsString() +
                " stacktrace: " + ExceptionUtils.getStackTrace(e));
        throw new KenectRestClientException("Failed to send request");
    } catch(ResourceAccessException e) {
        log.warning("Resource access exception " +
                " url: " + url +
                " stacktrace: " + ExceptionUtils.getStackTrace(e));
        throw new KenectRestClientException("Failed to send request");
    }
}

【问题讨论】:

  • 从另一个方法调用一个方法?

标签: java generics


【解决方案1】:

传递一个布尔标志怎么样,基于它你调用exchange() 传递Class&lt;T&gt;ParameterizedTypeReference&lt;T&gt;

public <T> T send(T neededType, boolean flag) throws KenectRestClientException {
    if (this.logRequest) log.info("Making request: " + this.toString());

    HttpEntity<Object> entity = new HttpEntity<>(this.body, getTokenHeaders(this.token));
    RestTemplate restTemplate = new RestTemplate();

    String compiledUrl = UrlUtils.replacePathParamsInUrl(this.url, this.pathParams, this.uriEncode) + UrlUtils.compileRequestParamsToUrl(this.requestParams, this.uriEncode);

    Object[] incompatibleStrings = extractIncompatibleStrings(compiledUrl);

    try {
        if (flag) {
            return restTemplate.exchange(compiledUrl, this.httpMethod, entity, neededType.getClass(), incompatibleStrings).getBody();
        } else {
            return restTemplate.exchange(compiledUrl, this.httpMethod, entity, ParameterizedTypeReference.forType(neededType.getClass()), incompatibleStrings).getBody();
        }

    } catch(RestClientResponseException e) {
        log.warning(RestClientResponseException.class.getSimpleName() +
                " url: " + url +
                " status code: " + e.getRawStatusCode() +
                " error body: " + e.getResponseBodyAsString() +
                " stacktrace: " + ExceptionUtils.getStackTrace(e));
        throw new KenectRestClientException("Failed to send request");
    } catch(ResourceAccessException e) {
        log.warning("Resource access exception " +
                " url: " + url +
                " stacktrace: " + ExceptionUtils.getStackTrace(e));
        throw new KenectRestClientException("Failed to send request");
    }
}

【讨论】:

  • 那行不通。 Java 无法推断出正确的类型。这是错误:不兼容的类型:推断的类型不符合上限 ParameterizedTypeReference> type = send(parameterizedTypeReference, false); ^ 推断:ParameterizedTypeReference 上限:ParameterizedTypeReference>,Object 其中 T 是类型变量:T 扩展方法中声明的对象 checkedSend(ParameterizedTypeReference)跨度>
  • 嗯。也许,我们可以直接使用Class&lt;T&gt; expectedClass 作为参数而不是T neededType,并根据标志将其传递给exchange(...)ParameterizedTypeReference.forType(expectedClass)。如果这也不起作用,或者不合适,那么对不起,我不知道我们还能尝试什么......
猜你喜欢
  • 2011-10-15
  • 2020-11-26
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 2013-07-27
相关资源
最近更新 更多