0

When the variable value is a primitive the finally block modification of the variable has no effect. However when value is an reference the finally block modification of the variable takes effect. Can you please help why this happens?

StringBuilder value = new StringBuilder("abc");

StringBuilder get() {

    try {
        throw new IndexOutOfBoundsException();
    } catch (IndexOutOfBoundsException e) {
        return value;
    } finally {
        value = value.append("def");
    }
}

 int value = 10;

int get() {

    try {
        throw new IndexOutOfBoundsException();
    } catch (IndexOutOfBoundsException e) {
        return value;
    } finally {
        value = value + 10;
    }
}
Athanasios V.
  • 319
  • 1
  • 4
  • 14
  • 6
    Why you do not try it out – Jens Mar 17 '17 at 08:10
  • 1
    @Jens ... If you know why, I'd like to know too ... the behavior is verified ! The primitive is indeed changed, but the return value is somehow incorrect. .. Seems as if the modification has an effect on the primitive but the return value remains what it was before the modification ... – Exception_al Mar 17 '17 at 08:18
  • 1
    simple, because you return the `ìnt` by value and not by reference, so the retuned value is not affected by the finally block, even if it gets executed. – xander Mar 17 '17 at 08:23
  • How did you verify? I am pretty sure, after the method is done, the returned value is unmodified while the field value is. – Fildor Mar 17 '17 at 08:37

2 Answers2

1

Since you are returning from try it self, the finally block gets executed and that will be discarded and won't get effected the originally returned value.

Again, Only returned value have no effect and the code block executed there will behave as is as any other java block, you can take an Object instead of primitive and check the behaviour.

And note that finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • Then how come the StringBuilder returns the modified value ? This does not clarify the doubt ... :( – Exception_al Mar 17 '17 at 08:42
  • 2
    @Exception_al Apples and Oranges. In StringBuilder's case, the *reference* returned is not changed. The caller will see the change because he accesses the value (that has been changed) through that reference. In int case it may be a different *value* (copy) returned. – Fildor Mar 17 '17 at 09:08
  • @Exception_al As mentioned in answer, ` you can take an Object instead of primitive and check the behaviour.` StringBuilder is an Object right ? – Suresh Atta Mar 17 '17 at 09:10
  • 2
    @Exception_al to be more precise: In int case, when the return in try is executed, the value to return is "fixed". Then the finally block is executed and changes the value of "value", which does not change the value that is fixed to be returned. I am not using the right terminology here but you get the gist of it, I hope. – Fildor Mar 17 '17 at 09:14
  • @ANS, if I were to return a String (also an Object as you insist), then also I get the unchanged value like with "int" ... so this has to do more with mutable / immutable answer as given by 668 – Exception_al Mar 17 '17 at 09:18
  • 2
    @Exception_al Strings *are* immutable objects. So if you change the String, you have a new reference. – Fildor Mar 17 '17 at 09:39
  • 2
    @Exception_al Though string is an Object in Java, it is Immutable. – Suresh Atta Mar 17 '17 at 09:42
  • And that is what I mean to say, the Mutable/Immutable answer clarified my doubt ! – Exception_al Mar 17 '17 at 09:42
  • @Exception_al Ah, ok. Then I misinterpreted your comment. Nevermind:) – Fildor Mar 17 '17 at 09:56
1

You will get the same answer for all immutable objects and primitives. All mutable objects will return the "changed" value whereas all immutable objects will retain their original value, thus finally do not have any effect.

7663233
  • 251
  • 1
  • 6