There's a lot going on here, but I think what it boils down to is that in the getStringBuilder version the returnVal object is mutable and the same object is mutated in the finally clause returning "1010" as you observed. On the other hand, a different value is returned when you add 10 to the integer in your finally clause that has a different address in memory than the value being returned.
Try running the following code to maybe better illustrate.
class MultipleReturn {
int getInt() {
int returnVal = 10;
System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
try {
String[] students = { "Harry", "Paul" };
System.out.println(students[5]);
} catch (Exception e) {
System.out.println("About to return :" + returnVal);
System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
return returnVal;
} finally {
returnVal += 10;
System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
System.out.println("Return value is now :" + returnVal);
}
return returnVal;
}
StringBuilder getStringBuilder() {
StringBuilder returnVal = new StringBuilder("10");
System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
try {
String[] students = { "Harry", "Paul" };
System.out.println(students[5]);
} catch (Exception e) {
System.out.println("About to return :" + returnVal);
System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
return returnVal;
} finally {
returnVal.append("10");
System.out.println("Return value is now :" + returnVal);
System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
}
return returnVal;
}
static class MutableInteger {
public int val;
@Override
public String toString() {
return Integer.toString(val);
}
}
MutableInteger getMutableInt() {
MutableInteger returnVal = new MutableInteger();
returnVal.val = 10;
System.out.println("Identiy hash of returnVal: " + System.identityHashCode(returnVal));
System.out.println(System.identityHashCode(returnVal));
try {
String[] students = { "Harry", "Paul" };
System.out.println(students[5]);
} catch (Exception e) {
System.out.println("Identiy hash of returnVal in catch block: " + System.identityHashCode(returnVal));
System.out.println("About to return :" + returnVal);
return returnVal;
} finally {
returnVal.val += 10;
System.out.println("Identiy hash of returnVal in finally: " + System.identityHashCode(returnVal));
System.out.println("Return value is now :" + returnVal);
}
return returnVal;
}
public static void main(String args[]) {
MultipleReturn var = new MultipleReturn();
System.out.println("In Main:" + var.getInt());
System.out.println();
System.out.println("In Main:" + var.getStringBuilder());
System.out.println();
System.out.println(var.getMutableInt());
}
}
Results:
Identiy hash of returnVal: 1152321476
About to return :10
Identiy hash of returnVal in catch block: 1152321476
Identiy hash of returnVal in finally: 2116610996
Return value is now :20
In Main:10
Identiy hash of returnVal: 814397217
About to return :10
Identiy hash of returnVal in catch block: 814397217
Return value is now :1010
Identiy hash of returnVal in finally: 814397217
In Main:1010
Identiy hash of returnVal: 1660743788
1660743788
Identiy hash of returnVal in catch block: 1660743788
About to return :10
Identiy hash of returnVal in finally: 1660743788
Return value is now :20
20