liveBook · Manning

Finally

As explained in Kotlin in Action, 2E

A finally block is an exception-handling block that executes after a protected block regardless of whether an exception was thrown.

A finally block performs cleanup after a protected try block, whether the operation completes normally or throws an exception. In Kotlin, it is especially useful for closing readers, unlocking locks, and releasing other resources. section 2.5.1 section 10.2.5

Closing a reader after parsing

fun readNumber(reader: BufferedReader): Int? { try { val line = reader.readLine() return Integer.parseInt(line) } catch (e: NumberFormatException) { return null } finally { reader.close() } } The try block reads and parses input, catch converts invalid input into null, and finally closes the reader in either case. Kotlin does not require a throws clause for this function, unlike Java's checked-exception style. section 2.5.1

Use finally when cleanup must not be skipped:

  • Acquire a resource before try, then release it in finally. section 10.2.5
  • Protect locks with the same pattern: lock before try, unlock in finally. section 10.2.5
  • Handle coroutine cancellation the same way; a finally block closes resources even when cancellation throws CancellationException. section 15.2.8
Listing 2.28 Using try the same way you would in Java
import java.io.BufferedReader
import java.io.StringReader
 
fun readNumber(reader: BufferedReader): Int? {    #1
    try {
        val line = reader.readLine()
        return Integer.parseInt(line)
    } catch (e: NumberFormatException) {          #2
        return null
    } finally {                                   #3
        reader.close()
    }
}
 
fun main() {
    val reader = BufferedReader(StringReader("239"))
    println(readNumber(reader))
    // 239
}

Inspect the complete Kotlin example showing parsing, exception recovery, and reader closure. section 2.5.1

inline fun <T> Lock.withLock(action: () -> T): T {      #1
    lock()
    try {
        return action()
    } finally {
        unlock()
    }
}

Compare explicit finally-based lock cleanup with Kotlin's higher-level withLock pattern. section 10.2.5

Listing 15.6 Using a finally block to close resources
val dbTask = launch {
   val db = DatabaseConnection()
   try {
       delay(500.milliseconds)
       db.write("I love coroutines!")
   } finally {
       db.close()
   }
}

See finally protect a database connection when a coroutine is cancelled during its work. section 15.2.8

How Kotlin in Action, 2E covers it

How deep it goes
Demonstrates syntax through parsing, locking, and cancellation examples, then defers routine resource cleanup to use and withLock.
Examples
Uses a BufferedReader parser, a lock, file-reading use, and a cancellable database connection.
What it assumes
Assumes basic Kotlin functions and exceptions while contrasting Kotlin's unchecked-exception model with Java's checked exceptions.
What you can do after
Apply it to write cleanup that remains reliable across normal completion, exceptions, and coroutine cancellation.
How it connects
Connects exception handling, try-catch, resource management, higher-order functions, coroutines, cancellation, and checked exceptions.

Also explained in

Compare how 2 books explain finally →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.