29

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?

Edit:

The question is not so much if it is a bug, that has been answered, but does it have nice use cases?

13
  • 2
    The question is one of the most interesting questions I have read this week. However, to my understanding, the try block can never throw an exception. Commented Dec 17, 2014 at 14:02
  • 1
    Very unexpected output !! Commented Dec 17, 2014 at 14:03
  • 4
    Question has a lot of duplicates. stackoverflow.com/questions/65035/… stackoverflow.com/questions/4185340/… stackoverflow.com/questions/19899155/… ... Commented Dec 17, 2014 at 14:04
  • 2
    A finally block has the right to override any return value. So your code should return "b". Commented Dec 17, 2014 at 14:04
  • 3
    @Hichamov What is unexpected in this output? Commented Dec 17, 2014 at 14:05

1 Answer 1

20

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 the finally 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.

Sign up to request clarification or add additional context in comments.

13 Comments

Ok, so no bug. Thanks, but what about a use-case
@Yuri I actually cannot think of a situation where this is useful.
@Yuri Why would this be useful?
@Yuri what is awesome about that?
@Tom you're not very good at code obfuscation, are you? ;-). Just kidding, I was being somewhat sarcastic as to the utter uselessness of this construction :-).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.