Effective Kotlin: Item 9 — Prefer try-with-resources to try-finally

Java 8 brings try-with-resources to Java as an improvement to try-finally when dealing with Closeable resources. One of the reasons item 9 of Joshua Bloch’s book, Effective Java, suggests try-with-resources as a winner is when dealing with multiple resources the ensuing nest of try-finally blocks becomes ever harder to read.

As discussed in item 8, Kotlin doesn’t have try-with-resources. Instead, it has the use extension function. However, unlike try-with-resources this only acts on a single Closeable resource so when dealing with multiple closeables you end up with nesting, albeit not quite as bad as with try-finally.

inputStream.use {
outputStream.use {
// do something with the streams
outputStream.write(inputStream.read())
}
}

If in your app you are constantly dealing with multiple resources then this can still look pretty messy, but with Kotlin’s extension methods we can help improve this situation:

private inline fun <T : Closeable?> Array<T>.use(block: ()->Unit) {
var exception: Throwable? = null
try
{
return block()
} catch (e: Throwable) {
exception = e
throw e
} finally {
when {
exception == null -> forEach { it?.close() }
else
-> forEach {
try
{
it?.close()
} catch (closeException: Throwable) {
exception.addSuppressed(closeException)
}
}
}
}
}

Allowing you to turn the original example into:

arrayOf(inputStream, outputStream).use {
// do something with the streams
outputStream.write(inputStream.read())
}

Each week I am looking at “items” from Joshua Bloch’s well-respected book, Effective Java to see how it applies to Kotlin. You can find the rest of the items I’ve covered at Effective Kotlin. Please let me know your thoughts.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store