0

As far as I know, in case of static variables if the value is changed in one place then it will be reflected in all the places. For example

static int i=0;

public static void test1()
   {
       System.out.println(i);
       i=100;
   }
   public static int test2()
   {
       return i;
   }

sysout of test1()--0 sysyout of test2()=100; again sysout of test1()=0

I am clear on this point.

But I am not clear on the below code

public static int test() {

    try {
        i = 2;
        System.out.println("before "+i);
        return i;
    } finally {
        i = 12;
        System.out.println("in finally");
    }
}

then why does it print 2 even though the value of i which is static is changed to 12; Below is the sequence of method calls;

test1();
      System.out.println(test2());
      test1();
      System.out.println(test());

outputs

0
100
100
before 2
in finally
2

EDIT

when I debug, I found the flow as try block->finally block->try blocks return statement. So in this case before the control goes to return statement,finally block is executed.So this means value of i is 12 then why it did not return 12

rocking
  • 4,729
  • 9
  • 30
  • 45
  • 1
    Check [Try , finally execution flow when return is in try block](http://stackoverflow.com/questions/27117764/try-finally-execution-flow-when-return-is-in-try-block) – sam Oct 31 '15 at 01:41

4 Answers4

3

that is a normal behavior because the last 2 you are printing is just the return value of the method test(). And as the return is executed before the finally block, meaning the value of i is copied into the return value before the value of i changes.

If you execute System.out.println(i); after executing the method test(), it prints 12.

~Fabian

Fabian Damken
  • 1,477
  • 1
  • 15
  • 24
  • when I debug, I found that the flow as try block->finally block-try blocks return statement. So in this case before the control goes to return statement,finally block is executed. then why i is not changed – rocking Oct 31 '15 at 01:42
  • That is hard to answer as I do not know. But I think this is just the fault of the debugger, as the return statement is executed before the finally block. I think that they have to display it in any way and that is what they did. – Fabian Damken Oct 31 '15 at 01:45
  • It's not debuggers fault... The return is done after the finally block... But the value for the return is computed before finally is executed (You will understand if you debug with a compound statement in return, like `return somemethodcall()`... So, it's computed that 2 should be returned, then finally block is executed, then the value is actually returned... – Codebender Oct 31 '15 at 01:47
  • Usefull answer,+1 but all my doubts are not cleared. – rocking Oct 31 '15 at 01:53
2

You print out the return value of test() as the last thing you do, not i.

When return i is executed, i is evaluated. So at that point you are effectively doing return 2;. So since i is already evaluated to 2, changing it in the finally block doesn't affect the already evaluated value in your return statement.

If you do

System.out.println(test());
System.out.println(i);

You'll see that i is 12.

See this for more information.

Community
  • 1
  • 1
nos
  • 223,662
  • 58
  • 417
  • 506
  • so you mean to say that return statement is evaluated but it did not return.It was waiting for finally to execute then it will return – rocking Oct 31 '15 at 01:48
  • Lets say I have I have method con() like the test() but in my con() the return type is Connection. And in finally I will close the connection. so when I Connection c=co(), then will it be null or it will have connection object. Hope you understand my question Else I will again code for it – rocking Oct 31 '15 at 01:52
  • Well, closing a connection doesn't set it to null. but if you did `return my_connection; } finally { my_connection.close(); my_connection = null;}`, the same thing apply, `c` will not be null in `Connection c = co();` but it will have the value(which is a reference to your Connection object) at the point of `return my_connection` - though since Connection is a reference, and you call `.close()` on it, it will still be closed. – nos Oct 31 '15 at 01:57
  • sorry I think I am not clear to you.My question is if I do `return my_connection; } finally { my_connection.close();}` and then `Connection c = co();` so here does the connection to DB still exists? Can i use c to to create preparedstatement,statement etc? – rocking Oct 31 '15 at 02:01
  • No, you closed that connection. The `my_connection` reference that you return refers (points to) to the same object that you closed in the finally block. – nos Oct 31 '15 at 02:05
1

It Prints '2' because When test() returns i, it is returning the current value of i, not whatever value it is when you use it. and since you returned i when the value is '2', when you print it, it is printing the value it was when you returned it. This is true for all basic types, such as int, boolean, double, and so on. But, if you return an Object, whenever you make changes to that returned object, you will make changes to the original object.

0
public static int test() {
    try {
        i = 2;
        System.out.println("before "+i);
    } finally {
        i = 12;
        System.out.println("in finally");
        return i;
    }
}

I changed your test() code above, because i think i know the problem. When you are calling System.out.println(test());, your old code was returning the value 2.

This was happening because you're return statement ( in the try block ) was called when i WAS infact equal to two. It's kinda weird java still executes the finally block but thats life!

You want it to return 12 yes? then add the return statement to the finally block. It'll give you some suppressable warnings but continue.

Ryan Turnbull
  • 3,766
  • 1
  • 25
  • 35