让我们考虑一个测试类
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;
}
}
}
如果我们按如下方式创建主要方法:
public static void main(String[] args){
TestClass instance = new TestClass();
instance.timer();
}
我们可以清楚地看到输出表明尝试在最终之前发生,就像我们期望的那样。打印时间对于我们大多数人来说都是毫无意义的,因为在我以及大多数其他机器上,该方法将在不到一毫秒的时间内执行,但是我认为Id包括它。
如果我们将主要内容改为
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.unaffectedReference());
}
我们打印出“重要信息”,这表明unaffectedReference()返回对String文字“Imporant msg”的引用,我们将其打印到控制台,只有在发生这种情况后才将指针更改为指向String对象“生活”。到目前为止有道理。
但是,如果我们将main更改为
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.modifiedReference().get());
}
我们得到“生命的意义”。注意,我们不保留对container的ModifiedReference()返回的引用。所以,如果它是
public static void main(String[] args){
TestClass instance = new TestClass();
Container container = instance.modifiedReference();
System.out.println(container.get());
}
这是有道理的。 modifierReference()返回一个引用,然后进入finally {},更改引用的对象,以及引用 - 然后才打印该值。那里发生了什么?最后在System.out.print()之前执行但是AFTER返回?怎么可能?
最后一个例子 -
public static void main(String[] args){
TestClass instance = new TestClass();
System.out.println(instance.finallyHappensBeforeReturn());
}
在这种情况下,我们得到一个StackOverflowError,它也表明最终会在返回之前发生。请注意,在抛出异常之前永远不会打印“重要消息”。
那么,问题是首先出现的问题 - 最终还是回归?
答案 0 :(得分:0)
没有那么多与之后执行的内容有关(它的尝试,捕获,返回,最后 - 最终在返回后运行,但在方法实际返回之前,所以它在技术上可以修改返回值 - 你不应该这样做)。基本的是要知道String是不可变的。
public String unaffectedReference(){
String message = "Important msg";
try{
return message;
}finally{
message = " meaning of life";
}
}
这将返回"重要消息",然后将消息(在方法中)更改为"生命的意义"。但返回值是对String"重要消息"的引用。而不是"消息"。如果String不是不可变的,你要做message.setValue("生命的意思"),那么这将被打印出来。
public Container modifiedReference(){
Container c = new Container();
c.set("Important msg");
try{
return c;
}finally{
c.set("Meaning of life");
}
}
...您的返回值是对Container对象的引用并更改内容INSIDE此Container对象修改返回值,当然,因为您返回一个对象并且此对象被修改。