Memra

finally, try-with-resources & multi-catch

◈ 6 cards

Guaranteed cleanup, automatic resource closing, and handling several exception types at once.

finally: cleanup that always runs

Some code must run no matter what — close a file, release a lock, restore a flag — whether the try succeeded, threw, or was exited early. A finally block attached to a try runs in all three cases:

try {
    risky();
} catch (IOException e) {
    System.out.println("failed: " + e.getMessage());
} finally {
    System.out.println("cleanup");   // runs whether or not risky() threw
}

The finally runs after the try completes normally, after a matching catch runs, and even if an exception propagates out with no matching catch (it runs on the way out). This is where you put the cleanup that cannot be skipped.

try-with-resources: cleanup done for you

Manual cleanup is easy to get wrong — forget the close(), or put it in the wrong place, and you leak file handles or sockets. Java's try-with-resources declares the resource in parentheses after try; any object that implements AutoCloseable is closed automatically when the block ends, success or failure:

try (BufferedReader in = new BufferedReader(new FileReader("examples1.txt"))) {
    String line = in.readLine();
    System.out.println(line);
}   // in.close() called automatically here, even if readLine() threw

There is no explicit close() and no finally — the language inserts the close for you, in the correct reverse order if you declare several resources separated by ;. This is the modern, preferred way to handle files and streams (you will use it throughout Module 8's I/O work).

Multi-catch: one handler, several types

When two or more exception types need the same recovery, repeating the handler is noise. Multi-catch combines them with |:

try {
    parseAndRun(file);
} catch (IOException | ControllerException e) {
    System.out.println("aborting: " + e.getMessage());
}

The variable e is effectively final and its static type is the nearest common supertype, so you may call only methods common to all the listed types (getMessage() is always safe — it's on Throwable). The caught types must not be subclasses of one another (you can't write IOException | FileNotFoundException — the broader one already covers the narrower).

Worked example — read an event file safely

try (Scanner sc = new Scanner(new File("examples1.txt"))) {
    while (sc.hasNextLine()) {
        System.out.println(sc.nextLine());
    }
} catch (FileNotFoundException | IllegalStateException e) {
    System.out.println("could not read events: " + e.getMessage());
}

Scanner implements AutoCloseable, so it is closed when the block ends regardless of how it ends. If the file is missing, the constructor throws FileNotFoundException; if something misuses a closed scanner, IllegalStateException — both land in the single multi-catch handler. No manual finally { sc.close(); } is needed.

no throwcleanup donetry { risky(); }completesfinally { ... }runs anywaynext statementafter the try
The path most people forget. Nothing is thrown, so the catch is skipped entirely — but finally is not the error path, and it still executes between the end of the try body and the next statement. That is what makes it a safe home for cleanup.
scenariotry bodycatchfinallyno exceptionruns fullyskippedrunsthrow, matchingcatchstops at the throwrunsrunsthrow, no matchstops at the throwskippedruns, thenpropagatesreturn inside tryruns up to thereturnskippedruns, then returnsOnly the finally column is never skipped.
Read the last column down: finally never says "skipped". An uncaught exception still runs it on the way out, and a return inside the try is held until finally completes — which is precisely why a return inside finally would overwrite it.
manual finally { close()}try-with-resourceswho closesyou, on every paththe languageclose after a throwonly if you wrote it therealwaystwo resourcesnested try/finallyreverse order, automaticrequiresnothingimplements AutoCloseablesuppressed-exception bugeasy to hithandledScanner and BufferedReader are both AutoCloseable.
Everything the manual form asks you to remember, the language does for you — including the reverse-order close and the suppressed-exception handling that a hand-written close gets wrong. The only requirement is that the resource implements AutoCloseable.
NORMAL ~/memra/learn/comp-308/finally-try-with-resources-multicatch utf-8 LF