Lets consider a test class
import java.util.Date;
public class TestClass {
public String finallyHappensBeforeReturn(){
try{
return "Important Message";
}finally{
finallyHappensBeforeReturn();
}
}
public String unaffectedReference(){
String message = "Important msg";
try{
return message;
}finally{
message = " meaning of life";
}
}
public Container modifiedReference(){
Container c = new Container();
c.set("Important msg");
try{
return c;
}finally{
c.set("Meaning of life");
}
}
public void timer(){
try{
System.out.println("Try time = " + new Date().getTime());
}finally{
System.out.println("Finally time = " + new Date().getTime());
}
}
class Container{
String s;
void set(String s){
this.s = s;
}
String get(){
return s;
}
}
}
If we create a main method as follows:
public static void main(String[] args){
TestClass instance = new TestClass();
instance.timer();
}
We can clearly see output that suggests that try happens before finally, like we would expect. Printing the time is kind of meaningless for most of us, since on my as well as most other machines the method will execute in less then a millisecond, but none the less I figured Id include it.
If we change the main to
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.unaffectedReference());
}
we get "Important msg" printed, which suggests unaffectedReference() returns a reference to String literal "Imporant msg", we print it to console, and only after that happens the pointer is changed to point to String object "Meaning of life". Makes sense so far.
However, if we change main to
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.modifiedReference().get());
}
we get "Meaning of life". Note, we do not keep a reference to the Container modifiedReference() returns. So, if it was
public static void main(String[] args){
TestClass instance = new TestClass();
Container container = instance.modifiedReference();
System.out.println(container.get());
}
it would make sense. modifierReference() returns a reference, then goes into finally{}, changes the object the reference, well, references - and only then the value is printed. What happened there? finally executed before the System.out.print() but AFTER return? How is that possible?
And, one last example -
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.finallyHappensBeforeReturn());
}
In this case we get a StackOverflowError, which also suggests that finally happens before return. Note that "Important Message" is never printed before the exception is thrown.
So, the question is which came first - the finally or the return?