5

When I try to execute the following function in Java:

public static int myfunc (int x) {
    try {
        return x;
    } finally {
        x++;
    }       
}
public static void main (String args[]) {
    int y=5,z;
    z = myfunc(y);
    System.out.println(z);
}

The output printed on the console is 5, where as one would expect 6 to be printed. Any idea why?

new_c_user
  • 123
  • 2
  • 12

5 Answers5

6

...would expect 6 to be printed. Any idea why?

The x++ happens after the value 5 has been read from x. Remember that what follows the return statement is an expression. When the return statement is reached, that expression is evaluated (its value is determined), and then that resulting value is used as the function's return value. So in myfunc, here's the order of what happens:

  1. Enter the try block.
  2. Evaluate the expression x (e.g., get the value of x).
  3. Set that value as the function's return value.
  4. Enter the finally block.
  5. Increment x.
  6. Exit the function using the return value from Step 3.

So as of when we leave the function, even though x is 6, the return value was determined earlier. Incrementing x doesn't change that.

Your code in myfunc is analogous to this:

int y = x;
x++;

There, we read the value of x (just like return x does), assign it to y, and then increment x. y is unaffected by that increment. The same is true for the return value of the function.

It might be clearer with functions: Assuming a foo function that outputs "foo" and returns 5, and a bar function that outputs "bar", then this code:

int test() {
    try {
        return foo();
    }
    finally {
        bar();
    }
}

...executes foo, outputting "foo", then executes bar, outputting "bar", and exits from test with the return value 5. You don't expect the function to wait to call foo until after the finally occurs (that would be strange), and indeed it doesn't: It calls it when it reaches the return foo(); statement, because it evaluates the expression foo(). The same is true of return x;: It evaluates the expression and remembers the result as of that statement.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
4

Finally block always executes but you returned the value in try block itself. After the value of x returned, x got incremented in finally.

public static int myfunc (int x) {
    try {
        return x;  // returning
    } finally {
        x++;   // now incremented.
    }       
}

Note: Just for testing, if you playing with try-catch-finally, just return in finally (not recommended) and see.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

Finally is executed no matter what, In this case the value is 5 which returned and then incrementing x.

package qwerty7;

public class Stack {
    public static int myfunc (int x) {
        try {
            return x;
        } finally {
            System.out.println("I'm executing!");
            x++;
        }       
    }
    public static void main (String args[]) {
        int y=5,z;
        z = myfunc(y);
        System.out.println(z);
    }
}

Output:
I'm executing!
5
Uma Kanth
  • 5,659
  • 2
  • 20
  • 41
-1

Just an addition and a lame version of others' answer

Let us consider this example below :

public class ok {

public static int foo1(int x) {
    try {
        x++;
        System.out.println("foo1 : Inside try before returning I am " + x);
        return x;
    } finally {
        x++;
        System.out.println("foo1 : Inside Finally after post Increment I am " + x);
    }
}

public static int foo2(int x) {
    try {
        x++;
        System.out.println("foo2 : I am inside another method, incremented and changed to " + x);
        return x;
    } finally {

    }
}

public static void main(String[] args) {
    ok o = new ok();
    int val = 10; // The father of all

    int z = foo1(val);
    System.out.println("After executing foo1 I am " + z);

    int x = foo2(val);
    System.out.println("After executing foo2 I am " + x);

    System.out.println("Inside main() and un-altered I am : " + val);
}
}

This is just a sample program for better understandability and synchronization of return, try, finally. Whereas, you also must consider the facts, very distinctively provided by :

  • MadProgrammer : return will supersede any other changes.
  • RishiKesh Pathak : return: returns control immediately to the caller of its method. And finally: will always be executed. but will wait for its turn

Thanks, Hope it helps.

P.S :- Parallely you must also consider accepting an answer here if you feel any of them have closely helped or completely solved your query

mustangDC
  • 945
  • 1
  • 12
  • 33
  • `return` doesn't 'supercede' anything.The relevant fact is that the *return-expresssion* is already evaluated before the `finally`block executes. – user207421 Jul 21 '15 at 08:50
  • I have just mentioned another person's comment to explain that even if there is a `finally` the `return` will execute and perform its duty first@EJP. In other words `JUST WHAT YOU HAVE TOLD`, may be `supercede` isn't the closest and perfect word – mustangDC Jul 21 '15 at 08:52
  • @EJP : Have I gone wrong anywhere other than the `supercede` word? Please rectify me, I would be happy to do so, – mustangDC Jul 21 '15 at 08:58
  • Your new attempt 'the `return` will execute and perform its duty first' is no better. It is simply untrue. What happens first is the *evaluation* of the *return-expression*, as I have already stated. Then the `finally` block. Then the `return`. That should be quite enough 'rectification' for anybody. And we don't need to be SHOUTED AT IN CAPITALS here. People are trying to sleep. – user207421 Jul 21 '15 at 10:30
  • I was not aware of "the **`evaluation`** of the return-expression", thanks for that but as it says it stands the same that **the `return` is executed first from the program stack while compiling**. Is not it the same regardless the `expression` and the `execution` thing? – mustangDC Jul 21 '15 at 10:39
  • If you think my capital letters have given an impression of `SHOUTING`, then I apologize for that. But my sole intention was to emphasize that `both are same` with respect to output. As far as `people are trying to sleep` is concerned, i personally think that *people are here to help this world rise and awake with possibilities of technology*. But Sorry if that previous comment has offended you. Thanks – mustangDC Jul 21 '15 at 10:55
-2

Value of x has returned from myfunc() before increment in finally block.