Kotlin 的 use 函数是 Java try-with-resources 的语义等价抽象,自动安全关闭 Closeable 对象:接收 Closeable? 参数,在 lambda 前进入 try 块,异常时先 close 再 re-throw,close 异常被抑制,返回 lambda 结果而非 Unit。

Kotlin 中的 use 函数就是 Java try-with-resources 的自然映射,不是语法转换,而是语义等价的资源管理抽象——它自动确保 Closeable(或 AutoCloseable)对象在作用域结束时被安全关闭。
use 的核心行为对标 try-with-resources
Java 的 try (Resource r = new Resource()) { ... } 要求资源实现 AutoCloseable,并在退出 try 块时(无论是否异常)调用 r.close()。Kotlin 的 use 做了完全一致的事:
- 接收一个可空或非空的
Closeable?对象(Kotlin 标准库中Closeable是AutoCloseable的 typealias) - 在 lambda 执行前不做额外检查,直接进入 try 块
- 若 lambda 抛异常,先 close 再 re-throw;若未抛异常,正常 close
- 即使 close 自身也抛异常,它会被抑制(suppressed),主异常仍向上抛出(与 Java 行为一致)
写法对比:一行 vs 三行
Java:
try (BufferedReader reader = Files.newBufferedReader(path)) {
return reader.readLine();
} catch (IOException e) {
throw new RuntimeException(e);
}
Kotlin:
立即学习“Java免费学习笔记(深入)”;
return Files.newBufferedReader(path).use { it.readLine() }
注意:use 是 Closeable 类型的扩展函数,所以调用主体必须是实现了该接口的对象;返回值是 lambda 的结果,不是 Unit。
嵌套资源怎么处理?
Java 支持多个资源声明:try (A a = ...; B b = ...) {...}。Kotlin 没有原生多资源语法,但可通过嵌套 use 实现相同效果:
FileInputStream(file).use { fis ->
BufferedInputStream(fis).use { bis ->
InputStreamReader(bis, charset).use { isr ->
BufferedReader(isr).use { br ->
br.readLine()
}
}
}
}
这和 Java 多资源的关闭顺序一致(逆序关闭:br → isr → bis → fis),且每层都独立捕获并处理 close 异常。
自定义类想用 use?必须实现 Closeable
就像 Java 要求实现 AutoCloseable,Kotlin 的 use 只接受 Closeable 类型。例如:
- 正确:任何
InputStream、OutputStream、Socket、Connection等标准类型都可用 - 错误:普通类即使有
close()方法,但没实现Closeable,就不能直接.use - 解决:包装成
Closeable或让类继承/实现该接口(推荐)
本质上,use 不是魔法,它是 Kotlin 标准库对 Java 资源管理契约的简洁封装——把样板逻辑收进高阶函数,让你只专注业务代码本身。


















