是否需同时关闭HttpURLConnection与InputStream?仅关连接能否关流?
HttpURLConnection与InputStream的关闭规范
核心问题解答
- 是否需要同时关闭?是的,建议显式同时关闭InputStream和HttpURLConnection
- 仅关闭连接会自动关流吗?理论上底层可能尝试关闭,但这不是可靠行为,绝对不能依赖
- 仅关连接为什么是不良实践?主要存在资源泄漏、连接池失效等风险,具体原因见下文。
为什么不能仅依赖disconnect()关闭流?
- 资源释放不及时:如果响应数据没有被完全读取,调用
disconnect()可能不会立即释放Socket等底层资源,这些资源会被占用直到GC回收,白白浪费系统资源。 - 连接池复用失效:HttpURLConnection默认使用连接池,若流未显式关闭就断开连接,连接池中的该连接可能处于无效状态,无法被后续请求复用,严重时会导致连接池耗尽,新请求无法获取连接。
- 兼容性差:不同JDK版本对
disconnect()处理流的逻辑存在差异,依赖这种隐式行为会让代码在不同环境下表现不一致,降低稳定性。
正确的代码示例(同时关闭两者)
HttpURLConnection con = (HttpURLConnection) obj.openConnection(); try (AutoCloseable ac = con::disconnect) { int responseCode = con.getResponseCode(); try (InputStream ins = responseCode >= 400 ? con.getErrorStream() : con.getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(ins))) { // 处理响应数据 } }
这里使用try-with-resources语法,会自动依次关闭BufferedReader、InputStream,最后调用disconnect(),确保所有资源都被正确释放。
需要避免的写法(仅关闭连接)
HttpURLConnection con = (HttpURLConnection) obj.openConnection(); try (AutoCloseable ac = con::disconnect) { int responseCode = con.getResponseCode(); BufferedReader in = new BufferedReader(new InputStreamReader(ins))) // ins will close automatically when con closes? // 处理响应数据 }
这个写法有两个明显问题:
ins变量未正确初始化,代码本身存在语法错误- 即使
ins初始化正确,仅依赖disconnect()关闭流不可靠,会引发前文提到的资源泄漏风险。
内容的提问来源于stack exchange,提问作者jpcairesf
相关产品推荐
相关产品推荐

