Search code examples
javaexceptiontry-finally

Try-finally block with return doesn't rise exception


In this code main method's Catch doesn't catch Runtime exception. after the execution of finally block, it should've gone to the exception block of main, but it doesn't.

 class FinallyDemo {
    static int m1(){
        try{
            System.out.println("Inside m1");
            throw new RuntimeException("hi");
        }
        finally {
            System.out.println("m1 finally");
            return 5;
        }
    }
    public static void main(String[] args) {
        try{
            System.out.println(m1());
        }catch (Exception e){
            System.out.println("main caught: "+ e);
        }
    }
}

Output:

Inside m1
m1 finally
5

Solution

  • (As noted in comments, the code as written wouldn't even compile, but that can be fixed without changing the core of the question.)

    it should've gone to the exception block of main, but it doesn't.

    No, it's behaving exactly as the spec section 14.20.2. There are lots of paths there, but the ones that are applied here are:

    • ...
    • If execution of the try block completes abruptly because of a throw of a value V
      • ...
      • If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally block is executed
        • ...
        • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).

    A return statement counts as "completing abruptly", as per section 14.1. So the whole try/finally statement completes abruptly for reason of "return with a value", just as if an exception hadn't been thrown.

    If you want the exception to propagate beyond the try/finally statement, don't use a return statement in the finally block.