1

I found this piece of code in a java certification website

   public class Test1{
        public static void main(String args[]){
            System.out.println(method());
        }
        public static int method(){
           try{
              return 1;
           }
           catch(Exception e){
              return 2;
           }
           finally{
              return 3;
           }
        }
    }

So the output of this piece of code is shown as 3. How is this possible..since it is returning 1 in the try block itself? The code will never reach finally right??

JSON C11
  • 11,272
  • 7
  • 78
  • 65
Akhil Nambiar
  • 315
  • 3
  • 18
  • 14
    A `finally` block will _always_ be executed; but `return`ing in `finally` is... Uh. Basically, that's a "don't do that" thing – fge Apr 09 '15 at 05:56
  • @fge explained pretty well – VedantK Apr 09 '15 at 06:05
  • 1
    You haven't tried to read something about the behaviour of a `finally` block, right? For example this: https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html – Tom Apr 09 '15 at 06:35
  • 1
    Also, related, and a good read if you're actually considering structuring your code this way for some reason: https://stackoverflow.com/questions/48088/returning-from-a-finally-block-in-java?rq=1 – Jason C Apr 09 '15 at 06:40

4 Answers4

2

The code will never reach finally right? No, If there is a finally block control will go to finally after try or/and catch

Because in any case finally will always execute. Except as Mike Kobit said System.exit

Thanks Jason C, From JLS 14.17. The return Statement

It can be seen, then, that a return statement always completes abruptly.

The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements (§14.20) within the method or constructor whose try blocks or catch clauses contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.

From JLS 14.20.2. Execution of try-finally and try-catch-finally

If execution of the try block completes normally, then the finally block is executed, and then there is a choice:

  1. If the finally block completes normally, then the try statement completes normally.
  2. If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.

So In you code try returns 1, then control goes to finally which returns 3. so return value of function will be 3.

Community
  • 1
  • 1
Sumit Singh
  • 15,743
  • 6
  • 59
  • 89
  • 2
    Well, nearly always. [*Certain* cases](http://stackoverflow.com/questions/12430642/what-are-the-circumstances-under-which-a-finally-block-will-not-execute) (like `System.exit`) it will not. – mkobit Apr 09 '15 at 05:56
  • But then is it possible to `return` a value from the `try` block? It seems like the answer is no. – Tim Biegeleisen Apr 09 '15 at 05:56
  • To which place in the call stack does the `try` block `return` the value 1? – Tim Biegeleisen Apr 09 '15 at 05:58
  • 1
    @TimBiegeleisen no, if you are returning something from finally too. – Sumit Singh Apr 09 '15 at 05:59
  • @TimBiegeleisen See the JLS for more details. – Sumit Singh Apr 09 '15 at 06:01
  • @SumitSingh This is a good answer although the piece of the JLS you quoted is incomplete. For completeness, add the foot note of 14.17, in particular, *"It can be seen, then, that a return statement always completes abruptly."* ties the behavior together by relating "completes abruptly" to "return". Also the part, *"... Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement."* – Jason C Apr 09 '15 at 06:55
2

As Sumit Singh mentioned in his answer, this happens because return causes the method to end abruptly.

You can observe the same behaviour, when you throw new Exceptions inside your try-catch-finally block, since throw is also abrupt.

See the following code:

public class FinallyTest {
    public static void main(String[] args) {
        abrupt();
    }

    @SuppressWarnings("finally")
    public static void abrupt() {
        try {
            throw new IllegalArgumentException("In Try");
        }
        catch(Exception x) {
            throw new IllegalArgumentException("In Catch");
        }
        finally {
            throw new NullPointerException("In Finally");
        }
    }
}

When running the code, the console shows

Exception in thread "main" java.lang.NullPointerException: In Finally
at FinallyTest.abrupt(FinallyTest.java:15)
at FinallyTest.main(FinallyTest.java:3)

Even though you throw a new IllegalArgumentException inside the try block, only the NullPointerException from the finally block is thrown, since this block ended abruptly.

QBrute
  • 4,405
  • 6
  • 34
  • 40
0

Finally block will always get executed just before return statement get executed. (There are some exceptions like JVM itself crash or system.exit() is called)

Here is the reason:

We normally use finally to free up our resources or to cleanup. Now if developer will write return statement accidentally in try block then logically finally would never get executed. To overcome this problem, JVM by itself handle this scenario and execute finally block just before returning from try block.

Remember the finally block always executes when the try block exits. And above explained scenario is also applied to return, continue, or break.

Unihedron
  • 10,902
  • 13
  • 62
  • 72
Hiren
  • 242
  • 1
  • 9
-2

Because if we think about priority finally has more than try or catch, to make it clear what if the exception haven't caught even then the finally executes and here it is working inside a method so logically when a method is suppose to return a single output int value then obviously it will always return values from finally.

Is it makes sense?

Pankaj Dubey
  • 146
  • 10
  • But since in the try block, it is returning a value, why would it still go and execute finally? – Akhil Nambiar Apr 09 '15 at 06:03
  • @AqeelSmith Because that's the very point of `finally`: to be finally executed whatever happens. It normally is used for cleanung up, such as `.close()`ing stuff. – glglgl Apr 09 '15 at 06:04
  • I am still not very clear about this! – Akhil Nambiar Apr 09 '15 at 06:05
  • As just not be very technical just for your understanding purpose, remember priorities `finally` has more than `try` or `catch` so finally wins the race in any case whether try works or catch – Pankaj Dubey Apr 09 '15 at 06:06