Kotlin 之 AutoCloseable.use()
介绍 Kotlin 的一个语言特性:AutoCloseable.use()
。
Java try-with-resources
Java 7 之前,只能使用 finally
子句来关闭资源,所以代码不太优雅。举个例子:
1 | static String readFirstLineFromFileWithFinallyBlock(String path) |
Java 7 引入了 try-with-resources 语句,它可以保证当前语句执行完毕后无论是否发生异常都能关闭资源。使用 try-with-resources 语句优化上述例子:
1 | static String readFirstLineFromFile(String path) throws IOException { |
不仅仅是 Java SDK 的内置资源(如 BufferedReader),任何实现了 java.lang.AutoCloseable
接口的资源都可以用在 try-with-resources 语句中。相当方便。
Kotlin AutoCloseable.use()
由于 Java 7 之后才支持 try-with-resources,所以 Kotlin 从 kotlin-stdlib-jre7
和 kotlin-stdlib-jre8
两个新包开始提供 AutoCloseable.use()
功能。
由于 AutoCloseable.use()
只是一个简单的扩展方法,代码量少且很清晰,这里直接贴完整的源码。
1 | /** |
简单总结关键点:
- 不同于 Java 7 中,try-with-resources 语句只对实现
AutoCloseable
接口的资源生效,Kotlin 中任何实现Closeable
接口的资源都会被自动关闭 use()
是扩展方法,它接收一个 block 对象,block 对象将receiver
(被扩展的那个对象) 作为参数。block 对象返回另一个类型为 R 的对象use()
方法最终会返回 block 对象的返回值
看个例子:
1 | fun getBitmap(): Bitmap { |
对照着 AutoCloseable.use()
扩展方法来解读上面的例子:
assets.open()
返回一个InputStream
实例InputStream
类实现了AutoCloseable
接口(AutoCloseable
是Closeable
的子类),所以可以对其应用use()
扩展方法{ return BitmapFactory.decodeStream(it) }
作为 block 对象传给use()
方法- block 对象将
it
(it
是receiver
) 解码成 Bitmap,并且返回该 Bitmap 对象 getBitmap()
返回 block 对象返回的 Bitmap