Java返回引用还是对象?最后回来?

时间:2015-08-05 04:19:59

标签: java return try-finally

让我们考虑一个测试类

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,它也表明最终会在返回之前发生。请注意,在抛出异常之前永远不会打印“重要消息”。

那么,问题是首先出现的问题 - 最终还是回归?

1 个答案:

答案 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对象修改返回值,当然,因为您返回一个对象并且此对象被修改。