关于 Java 中 try...catch...finally 语句的一点儿疑问

Shawearn 发布于 2014/06/12 22:44
阅读 346
收藏 1
都说 finally 是总会执行的,但我一直很好奇 try...catch...finally 的执行顺序,于是今天试着写了一下这段代码:


public class Test {

        public String test() {
                String a = "This is the return of try !";
                String b = "This is the return of catch !";
                String c = "This is finally !";
                try {
                        return a;
                } catch (Exception e) {
                        // TODO: handle exception
                        return b;
                } finally {
                        System.out.println(c);
                }
        }

        public static void main(String[] args) {
                Test t = new Test();
                // 打印输出 test() 方法中的返回值
                System.out.println(t.test());
        }
}


运行结果如下:
        This is finally !
        This is the return of try !
也便是说 finally 是在 try 的 return 之前执行的,于是我在 finally 中将 a 赋值为 null ,代码修改如下:

public class Test {

        public String test() {
                String a = "This is the return of try !";
                String b = "This is the return of catch !";
                String c = "This is finally !";
                try {
                        return a;
                } catch (Exception e) {
                        // TODO: handle exception
                        return b;
                } finally {
                        // 新加的语句,将a赋值为 null
                        a = null;
                        System.out.println(c);
                }
        }

        public static void main(String[] args) {
                Test t = new Test();
                System.out.println(t.test());
        }
}


按理说运行结果应该如下:
        This is finally !
        null
可运行结果却是如下:
        This is finally !
        This is the return of try !


我想难道是 a 没有被赋值为 null ?于是我又在 finally 中加了一行输出 a 的语句,代码如下:
public class Test {

        public String test() {
                String a = "This is the return of try !";
                String b = "This is the return of catch !";
                String c = "This is finally !";
                try {
                        return a;
                } catch (Exception e) {
                        // TODO: handle exception
                        return b;
                } finally {
                        a = null;
                        // 新加的语句,测试 a 是否已经为 null
                        System.out.println(a);
                        System.out.println(c);
                }
        }

        public static void main(String[] args) {
                Test t = new Test();
                System.out.println(t.test());
        }
}


如果 a 未被成功赋值为 null,那么结果应该如下:
        This is the return of try !
        This is finally !
        This is the return of try !


可结果却不是我预料的那样,而是如下结果:
        null
        This is finally !
         This is the return of try !


我表示已经快晕死了,难道 finally 中的 a 所指向的内存地址跟 try 中的 a 所指向的内存地址不一样?
加载中
0
憨厚的瓜
憨厚的瓜

主要问题在你的return上面, finally是一个代码块最后执行的这没有问题

从你的例子上可以看到执行顺序

  1. return a
  2. 在finally中print(c)
  3. System.out.println(t.test());

看这个顺序return a 在finally 的前面执行的,但关键是 :

return a 并不代表立即执行System.out.println(t.test()); 块内代码是要先执行完的,所以return后面是执行finally

这中间还经过了一次参数传递

你可以这么理解,return a 到 System.out.println(t.test())之间的过程类似就像

String a = "some some";
String a2 = a;
a=null;
print(a); // null
print(a2); // some some

你可以把return a 理解成 a2=a 这句的概念差不多,所以你在finally中再怎么更改a的内容也不会影响到已经return的返回值

0
Shawearn
Shawearn

引用来自“Panying”的评论

主要问题在你的return上面, finally是一个代码块最后执行的这没有问题

从你的例子上可以看到执行顺序

  1. return a
  2. 在finally中print(c)
  3. System.out.println(t.test());

看这个顺序return a 在finally 的前面执行的,但关键是 :

return a 并不代表立即执行System.out.println(t.test()); 块内代码是要先执行完的,所以return后面是执行finally

这中间还经过了一次参数传递

你可以这么理解,return a 到 System.out.println(t.test())之间的过程类似就像

String a = "some some";
String a2 = a;
a=null;
print(a); // null
print(a2); // some some

你可以把return a 理解成 a2=a 这句的概念差不多,所以你在finally中再怎么更改a的内容也不会影响到已经return的返回值

明白了,谢谢你的指点。
0
木木三
木木三

记住一点方法调用是值传递

返回顶部
顶部