潜在的资源泄漏警告

时间:2018-08-21 15:45:15

标签: java

Eclipse抱怨response.body()可能是潜在的资源泄漏。这里真的有泄漏吗?该文档说response.body()。string()将关闭资源。

请明确一点,我了解如何(尝试使用资源)来解决警告。我只是想知道在什么情况下资源会真正泄漏到这里?如果不为null,它将自动关闭。如果为空,那么...那么没有什么可关闭的...?

响应为: okhttp3.Response

try {
    if (response.body() != null) {
        String respBody = response.body().string();
    }
} catch (IOException e) {
    throw new ApiException(e);
}

根据答案之一,我尝试执行以下操作并收到相同的警告:

try {
    ResponseBody body = response.body()
    if (body != null) {
        String respBody = body.string();
    }
} catch (IOException e) {
    throw new ApiException(e);
}

2 个答案:

答案 0 :(得分:2)

javadoc显示了如何正确使用它:

try (ResponseBody responseBody = response.body()) {
    ... // Use the response.
}

这将自动向其添加一个finally子句。这样可以正确读取关闭流期间的异常。

编辑2

进行更多研究后,似乎可以正确关闭资源(无泄漏)。

Eclipse报告警告,因为它没有检查string()方法是否正确关闭了资源。实际上,eclipse不会使用任何方法来检查此警告(因此,如果编写了自己的close方法,则会收到此警告)。这意味着它在这种情况下报告为误报。

之所以这么做,是因为很难/不可能检查所有能够及时关闭资源的实现。

但是,将try与资源一起使用仍然是一个好习惯,因为这样您就不必担心基础代码如何处理内容。

答案 1 :(得分:1)

当您检查response.body() != null时,我相信您正在创建ResponseBody的新流,即使您在String respBody = response.body().string()行之后,该流仍处于打开状态。因为您将此流保持打开状态,所以它会向您发出潜在的资源泄漏警告。

Pinkie Swirl的answer应该使用try-with-resource方法解决您的问题。

至于您的编辑以显示您尝试的第二种方法,我想它会发出警告,因为Eclipse无法看到.string()正在关闭对象ResponseBody body的流。但是,我也可以说这可能是警告,因为它可能仍在创建流,并且如果body为空,则它永远不会关闭,因为从未调用过.string()

在处理完对象之后,显式调用.close()并没有什么害处。无论如何,这样做可能是最佳做法,因为您有条件地执行此步骤。自动关闭.string()中的流很奇怪,但是您对此无能为力。