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
(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 thefinally
block is executed
- ...
- If the
finally
block completes abruptly for reason S, then thetry
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.