Java return 引用还是对象? Return 之前最后?

Java return reference or object? Return before finally?

让我们考虑一个测试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;
        }
    }
}

如果我们创建一个main方法如下:

public static void main(String[] args){
    TestClass instance = new TestClass();
    instance.timer();
}

我们可以清楚地看到表明 try 在 finally 之前发生的输出,正如我们所期望的那样。打印时间对我们大多数人来说有点毫无意义,因为在我和大多数其他机器上,该方法将在不到一毫秒的时间内执行,但 none 我认为 Id 包含它的时间越少。

如果我们将 main 更改为

public static void main(String[] args){
    TestClass instance = new TestClass();
    System.out.println(instance.unaffectedReference());
}

我们得到 "Important msg" 打印,这表明 unaffectedReference() return 是对字符串文字 "Imporant msg" 的引用,我们将它打印到控制台,只有在那之后指针才会改变指向字符串对象 "Meaning of life"。到目前为止说得通。

但是,如果我们将 main 更改为

public static void main(String[] args){
    TestClass instance = new TestClass();
    System.out.println(instance.modifiedReference().get());
}

我们得到 "Meaning of life"。请注意,我们不保留对 Container modifiedReference() return 的引用。所以,如果是

public static void main(String[] args){
    TestClass instance = new TestClass();
    Container container = instance.modifiedReference();
    System.out.println(container.get());
}

这是有道理的。 modifierReference() return 是一个引用,然后进入 finally{},将对象更改为引用,嗯,引用 - 然后才打印值。那里发生什么了?最终在 System.out.print() 之前但在 return 之后执行?这怎么可能?

最后一个例子 -

public static void main(String[] args){
    TestClass instance = new TestClass();
    System.out.println(instance.finallyHappensBeforeReturn());
}

在这种情况下,我们得到一个 WhosebugError,这也表明最终发生在 return 之前。请注意 "Important Message" 在抛出异常之前从未打印过。

所以,问题是哪个先出现 - 最后还是 return?

与在什么之后执行什么没有太大关系(它是 try、catch、return、finally - finally 在 return 之后运行,但实际上在方法之前 returns,所以它在技术上可以修改 return 值 - 你不应该那样做)。最基本的是要知道 String 是不可变的。

   public String unaffectedReference(){
    String message = "Important msg";
    try{
        return message;
    }finally{
        message = " meaning of life";
    }
   }

这将 return "Important msg",然后将消息(在方法中)更改为“生命的意义”。但是 return 值是对字符串 "Important message" 而不是 "message" 的引用。例如,如果 String 不是不可变的并且您要执行 message.setValue(" meaning of life"),那么这将被打印出来。

 public Container modifiedReference(){
    Container c = new Container();
    c.set("Important msg");
    try{
        return c;
    }finally{
        c.set("Meaning of life");
    }
}

...您的 return 值是对 Container 对象的引用,更改此 Container 对象内部的内容会修改 return 值,当然,因为您是 return对象和此对象被修改。