Warm-up

Watch finally eat an exception

5 minfresher04 yrs

One concept, guided. Near-impossible to fail.

What this teaches

  • A return inside finally discards an in-flight exception
  • The return value is copied before finally runs, so mutating the local is a no-op
  • finally runs even when the catch block itself throws
  • Chaining the cause is what keeps the original error reachable

Starter

Starter.java
/**
 * Warm-up: finally is not as safe as it looks.
 *
 * Predict all three outputs before running. Two of them are counter-intuitive
 * and both appear in real code.
 */
public class Starter {

    /** What does this return? Write it down first. */
    static int copiedBeforeFinally() {
        int x = 1;
        try {
            return x;
        } finally {
            x = 2;
        }
    }

    /** And this one? Where did the exception go? */
    @SuppressWarnings("finally")
    static int swallowed() {
        try {
            throw new RuntimeException("you will never see this");
        } finally {
            return 42;
        }
    }

    public static void main(String[] args) {
        System.out.println("copiedBeforeFinally() = " + copiedBeforeFinally());
        System.out.println("swallowed()           = " + swallowed());

        try {
            throw new IllegalStateException("first");
        } catch (IllegalStateException e) {
            System.out.println("caught: " + e.getMessage());
            // TODO 1: throw a new IllegalArgumentException from here WITHOUT
            // passing e as the cause. Catch it outside and print its
            // getCause(). What do you get?
        } finally {
            System.out.println("finally ran");
        }

        // TODO 2: do it again, this time passing e as the cause:
        //     new IllegalArgumentException("second", e)
        // Print the full stack trace of the outer exception. How many
        // "Caused by:" sections do you see?

        // TODO 3: in a comment, say why swallowed() is legal Java and what a
        // linter would tell you about it.
    }
}

Run it locally:

cd exercises/java/exceptions/checked-vs-unchecked-exceptions/01-warmup
javac Starter.java -d /tmp/out && java -cp /tmp/out Starter

Done when

  • You made an exception disappear without any catch block
  • You can explain why f() returns 1 and not 2
  • You printed a two-level stack trace using an exception cause

← Back to What is the difference between checked and unchecked exceptions?