Java 作者为什么使用EntityUtils.consume(httpEntity);?

Java 作者为什么使用EntityUtils.consume(httpEntity);?,java,apache-httpclient-4.x,Java,Apache Httpclient 4.x,我遇到了EntityUtils.consume(httpEntity)我不确定它到底是做什么的 例如: try { //... some code HttpEntity httpEntity = httpResponse.getEntity(); BufferedReader br = new BufferedReader(new InputStreamReader(http.Entity.getContent())); String line; wh

我遇到了
EntityUtils.consume(httpEntity)我不确定它到底是做什么的

例如:

try {

    //... some code

    HttpEntity httpEntity = httpResponse.getEntity();
    BufferedReader br = new BufferedReader(new InputStreamReader(http.Entity.getContent()));
    String line;
    while ((line = br.readLine())!= null) {
        System.out.println(line);
    }
    EntityUtils.consume(httpEntity);
} catch (Exception e) {
    //code
} finally { 
    httpClient.getConnectionManager().shutdown();
}

作者为什么要输入
EntityUtils.consume(httpEntity)
最后
块将关闭连接,垃圾收集器将处理
httpEntity

它实际上归结为是一个“好公民”(并且真正了解
HTTPClient
接口的合同)。
EntityUtils.consume
将要做的是释放
httpEntity
所持有的所有资源,这本质上意味着释放任何底层流并将连接对象返回到其池(如果您的连接管理器是多线程的)或者释放连接管理器,以便它可以处理下一个请求

如果您不使用
实体
,发生的情况实际上取决于finally子句中“关闭连接管理器”的含义。它是否会关闭尚未发送回池的挂起流/连接?我不确定它是否会在合同上做到这一点(尽管我认为它在实现方面做到了)。如果没有,那么您可能正在泄漏系统资源(套接字等)。 所发生的事情也可能取决于实体对象的可能终结方法,该方法可能(如果它被执行的话)释放其资源,同样,也不确定它是否在实体的契约中这样做

让我们假设一分钟,
ConnectionManager
实际上在关闭时优雅地关闭了所有挂起的资源。您是否仍需要使用该实体?我说是的,因为一个月后,有人会修改您的代码并在同一个try/finally块中进行第二次HTTP调用,并且可能无法这样做,因为您没有以应有的方式释放资源(例如,如果您的客户端位于单个连接池上,不释放第一次连接将导致第二次调用失败)

所以我的观点是:实体是资源,不需要资源时应该释放资源。指望别人在以后为你释放他们可能会伤害你的未来。原作者可能是按照这些思路思考的

作为旁注,请注意,您编写的实现实际上会将读卡器一直消耗到底层流的末尾,因此消费调用实际上什么都不会做,但在我看来,这是一个实现细节(想不到,一旦响应流被完全读取,连接对象就会自动释放/发送回http客户端中的池)。 还要注意的是,如果您使用API提供的ResponseHandler mecanism,那么所有这些消费逻辑也会从您这里抽象出来。 最后,API不能保证
response.getEntity
永远不会返回null,因此您应该检查它以避免
NullPointerException