I was wondering why the following code would be accepted by the Java compiler:
public class Main { public static void main(String ... args){ System.out.println("a() = " + a()); } public static String a (){ try { return "a"; }catch(Throwable t){ }finally{ return "b"; } } }
This can and should not work. The java specification states the finally
block will always be executed, but at the same time the return value has already been specified. So either you cannot execute the return "b"
statement, because you have exited at return "a"
, which would be incorrect.
However, the other option is that you execute the return "b"
statement, and thereby totally disregarding the return "a"
statement...
I would say that both are wrong, and I would expect that this does not compile. However it compiles and runs fine. I will leave the answer as a nice exercise to the reader ;).
Basically my question is: Besides being bad practice, would this be considered a Java bug, or does this have other wonderful uses other than obfuscation?
The question is not so much if it is a bug, that has been answered, but does it have nice use cases?
Yes, the finally block will be executed even after a return statement in a method. The finally block will always execute even an exception occurred or not in Java.
The try statement defines the code block to run (to try). The catch statement defines a code block to handle any error. The finally statement defines a code block to run regardless of the result. The throw statement defines a custom error. Both catch and finally are optional, but you must use one of them.
Yes, we can write a return statement of the method in catch and finally block. There is a situation where a method will have a return type and we can return some value at any part of the method based on the conditions.
Yes, it absolutely will. Assuming your finally block doesn't throw an exception, of course, in which case that will effectively "replace" the one that was originally thrown.
Everything works exactly as expected, no bugs here. When you have doubts, the JLS is your savior:
JLS - 14.20.2. Execution of try-finally and try-catch-finally:
If execution of the
try
block completes abruptly for any other reason R, then thefinally
block is executed, and then there is a choice:
If the finally block completes normally, then the try statement
completes abruptly for reason R.If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is
discarded).
It overrides the value in the try
block.
return
inside finally
discards all exceptions that can be thrown in try
clause.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With