【问题标题】:Java: try-catch-resources with return and throw new statements [duplicate]Java:带有返回和抛出新语句的try-catch-resources [重复]
【发布时间】:2021-08-27 04:19:31
【问题描述】:

这是我的角色:

private ResultSetType makeRequest() {
    try (CloseableHttpResponse response = this.sendRequest(request)) {
        String responseBody = IOUtils.toString(
            response.getEntity().getContent(),
            StandardCharsets.UTF_8
        );
            
        if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
            // do something;
            return ...
        } else {
            throw new LoaderSystemFault(LoaderConstants.ErrorCodes.ERR_002, "Communication error with Servei Territorial (status-code: {0} / request: {1} / response: {2})", response.getStatusLine().getStatusCode(), request, responseBody);
        }
    } catch (IOException | JAXBException e) {
        throw new LoaderSystemFault(LoaderConstants.ErrorCodes.ERR_002, "Communication error with Servei Territorial (status-code: {0} / request: {1} / response: {2})", response.getStatusLine().getStatusCode(), request, responseBody);
    }
}

我的目标是关闭CloseableHttpResponse

这里有几个问题:

  • try-catch-resources 中的 return 语句呢?
  • throw new 语句呢?

无论是否达到returnthow new 语句,我都不清楚CloseableHttpResponse 是否会关闭。

如何重构上面的代码?

有什么想法吗?

【问题讨论】:

  • 它将通过所有可能的路径关闭。无需更改您的代码。
  • 您想用“try-catch-resources 中的 return 语句怎么样?”来问什么? “我很清楚 CloseableHttpResponse 是否会关闭,无论是否返回或到达新语句。”这不是已经回答了吗?
  • “X 呢?”不是一个明确的问题。你的问题是那些东西呢?
  • @Sweeper 写错了,我的意思是“我不清楚”。解决了。​​
  • 好吧,当你问对方的意思时,它并没有多大帮助。

标签: java try-catch try-catch-finally


【解决方案1】:

根据Java Language Specification,一个try-with-resources 像你有的那样首先被翻译成:

try {
    try (CloseableHttpResponse response = this.sendRequest(request)) {
        String responseBody = IOUtils.toString(
            response.getEntity().getContent(),
            StandardCharsets.UTF_8
        );
            
        if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
            // do something;
            return ...
        } else {
            throw new LoaderSystemFault(LoaderConstants.ErrorCodes.ERR_002, "Communication error with Servei Territorial (status-code: {0} / request: {1} / response: {2})", response.getStatusLine().getStatusCode(), request, responseBody);
        }
    }
} catch (IOException | JAXBException e) {
    throw new LoaderSystemFault(LoaderConstants.ErrorCodes.ERR_002, "Communication error with Servei Territorial (status-code: {0} / request: {1} / response: {2})", response.getStatusLine().getStatusCode(), request, responseBody);
}

内部的 try-with-resources 现在是一个基本的 try-with-resources 语句,翻译如下:

{
    final CloseableHttpResponse response = this.sendRequest(request);
    Throwable #primaryExc = null;

    try {
        // everything in your try block
    } catch (Throwable #t) {
        #primaryExc = #t;
        throw #t;
    } finally {
        if (response != null) {
            if (#primaryExc != null) {
                try {
                    response.close();
                } catch (Throwable #suppressedExc) {
                    #primaryExc.addSuppressed(#suppressedExc);
                }
            } else {
                response.close();
            }
        }
    }
}

需要注意的重要一点是原始try-with-resources中的块被翻译成try-catch-finally的try块,而资源的关闭是在finally块中完成的.

这意味着普通 try-catch-finally 语句的语义在这里适用 - 如果try 块突然完成(即返回或抛出)或者如果它正常完成,finally 块将 em> 被执行。有关详细信息,请参阅§14.20.2。你会看到finally 在规范中提到的每一种情况下都会被执行。

因此,总而言之,即使达到returnthrow,您的资源也会关闭。

【讨论】:

    猜你喜欢
    • 2014-03-10
    • 2013-11-22
    • 1970-01-01
    • 2014-06-18
    • 2014-08-25
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 2018-10-14
    相关资源
    最近更新 更多