Search code examples
javatry-catch-finally

Why is a "finally" block required in this code


I am aware that it is valid to create a try-catch segment without a finally block. So in hacking around with this code, I can't figure out what java logic (e.g. rule, theory) forces me to include a finally block in this segment of code - and why the finally block has to include a return statement in it. In other words, if I remove the finally block completely I receive an error, and if I replace the return statement in the finally block with anything else (e.g. System.out.printl(''foo")), I still receive an error insisting that I include a return statement. Again, the code as written here compiles and runs fine. I'm just trying to understand a little bit of the theory behind the try-catch-finally construct (p.s. I understand that its all about "exception handling"... but my question is really more about code flow and the return statement).

class foo {
    int getInt() {
        try {
            String[] students = {"student1", "student2"};
            System.out.println(students[4]);
        }
        catch (Exception e) {
            return 10;
        }
        finally {
            return 20;
        }
    }
    public static void main(String args[]) {
        foo classSize = new foo();
        System.out.println(classSize.getInt());
    }
}

Solution

  • Consider the execution paths without the finally

    int getInt() {
        try {
            String[] students = {"student1", "student2"};
            System.out.println(students[4]);
            // no return
        }
        catch (Exception e) {
            return 10; // if an exception occurs 
        }
        // no return
    }
    

    So what happens if no exception is thrown? You won't have a return value.

    You can either provide a finally and put a return there or you can put a return outside the try-catch block.

    Note that the finally in your try-catch-finally block has a return statement that will supersede the catch's return statement since a finally block is always executed if its associated try[-catch] is executed. You may want to go with the following

    int getInt() {
        try {
            String[] students = {"student1", "student2"};
            System.out.println(students[4]);
            // the return could be here as well
        }
        catch (Exception e) {
            return 10; // in case of failure
        }
        return 20; // in case of success
    }
    

    All execution paths must end up returning a value (or throwing an exception).