object reference set to null in finally block
Asked Answered
H

3

12
public void testFinally(){
System.out.println(setOne().toString());

}

protected StringBuilder setOne(){
StringBuilder builder=new StringBuilder();
try{
builder.append("Cool");
return builder.append("Return");
}finally{
builder=null; /* ;) */
}
}

why output is CoolReturn, not null?

Regards,
Mahendra Athneria

Hayrick answered 7/1, 2011 at 12:55 Comment(0)
T
14

The expression is evaluated to a value in the return statement, and that's the value which will be returned. The finally block is executed after the expression evaluation part of the return statement.

Of course, the finally block could modify the contents of the object referred to by the return value - for example:

finally {
  builder.append(" I get the last laugh!");
}

in which case the console output would be "CoolReturn I get the last laugh!" - but it can't change the value which is actually returned.

Transubstantiate answered 7/1, 2011 at 12:57 Comment(8)
@Jon, but why does builder.append("some value"); modify the actual returned value while builder = null not?Reticle
@Darin: Because builder is a reference. Setting a reference to null unsets said reference, but the object it referenced still exists until it is garbage collected. append, on the other hand, modifies the object (or one of its properties)Lailalain
@Darin: append method returns link to the variable on which it was called. So return builder.append("some value"); actually appends "some value" to the builder and returns link to builder as object, which you change in finally block. When you write builder = null you just change where builder points, but not value which was located under old link.Resolution
@Resolution - as you said by writing builder=null we are just changing the builder points. i agreed. but in return we are returning reference, and now that is referring to null. so it should use the value pointed by the new reference. am i clear to you?Hayrick
@Mahendra you evaluated this reference in return ..., and you can't change it just changing builder variable pointer. You can write "return ..." in finally block, and then another object can be returnedResolution
@Mahendra when program executes "return ..." it writes link to an object in stack, and you can't change it just changing builder reference, because that reference was already evaluated and pushed in stack. Maybe this way is better to explainResolution
@Resolution - you mean to say in return statement it use the builder old reference which contain value "CoolReturn". and in finally block we are modifying builder reference which is unknown to return. so it return old value. but if i'll append something in finally block for example "builder.append("some new value")"then it append it on old reference value i.e in "CoolReturn some new value". and it will return "CoolReturn some new value". Great Explanation @Maxym. my doubt is clear. thanks :-)Hayrick
@Mahendra feel free to ask more, and feel free to investigate and discover beautiful world of java ;)Resolution
G
2

apparently it looks it should be null but with the concept of pass by reference in java here is how it goes :

1> return builder.append("Return")... line gets executed and the copy of builder reference is returned to the testFinally() method by pass by reference

2> While executing builder=null in finally block the builder reference gets dereferenced but the actual object which is in the heap which was referenced by the builder reference earlier still present in the heap and the returned copy of the builder reference (which is also a reference pointing to the same object) still exists and that's holding the value "CoolReturn" , thats why its printing the returned value .

Garrek answered 22/4, 2013 at 13:6 Comment(0)
W
0

The finally block is used for "cleanup", after the execution of the try block. As you returned the reference already, you can not change it in this way.

Warpath answered 7/1, 2011 at 12:57 Comment(2)
I think that's slightly misleading - if the finally block throws an exception, for example, that will still end up being thrown. I think it's clearer to separate out the evaluation of the return value (which occurs before the finally block) and the transfer of control out of the method back to the caller (which occurs after the finally block).Transubstantiate
you are right, I will change my wording. But your answer is good anyway ;-)Warpath

© 2022 - 2024 — McMap. All rights reserved.