trycatchfinally顺序及return

92次阅读

共计 1146 个字符,预计需要花费 3 分钟才能阅读完成。

今天看代码,遇到 try-with-resource 的语法。这一语法不太熟,因为之前一直以为是 jdk8 才有的,所以没怎么关注。网上查了下资料,发现原来 jdk7 就有了,真是惭愧。
try-with-resource 的作用是,针对需要自己释放资源的对象,无需通过 finally 代码块,而可以自动释放资源。只要资源对象实现了 AutoCloseable 接口。
如何做到自动释放资源呢?通过反编译.class 文件,发现编译器最终还是将 try-with-resource 代码,转换成了 try-catch-finally 格式。
然后引出了这样一个问题:try-catch-finally 的执行顺序是什么?
认真想了想,竟然对这块有点摸棱两可了,只能再查查资料,解除疑惑。

finally 代码块,一般用于释放资源,因为它的代码始终会被执行,即使 try 块中产生了异常或者 return。这也是为何要用 finally 的原因。否则,try 块中要释放资源,catch 中也要释放资源,导致代码重复了。
try-catch-finally 的执行顺序是:try->catch->finally。即 try 执行完后,才执行 finally。或者 try 中产生了异常,会执行 catch 中的代码,最后执行 finally 的代码。但是切记:finally 的代码,是在 try 或者 catch 代码块的 return 之前执行。

注意:finally 中不要写 return,否则会导致 try 和 catch 中的 return 失效。因为 finally 中 return 了,就不会再执行 try 中的 return 或者 catch 中的 return 了。

还有一点注意,try 和 catch 块 return 之前,会执行 finally 代码。然后执行 finally 之前,会暂时保存需要 return 的信息,执行完 finally 后,再 return 保存的信息。

看代码:

public static void main(String[] args) {System.out.println(testReturn());
}


private static int testReturn() {
    int i = 1;
    try {
        i++;
        System.out.println("try:" + i);
        return i;
    } catch (Exception e) {
        i++;
        System.out.println("catch:" + i);
        return i;
    } finally {
        i++;
        System.out.println("finally:" + i);
    }
}

执行结果:

try:2
finally:3
2

这里,restReturn 返回的是 2,而不是 3。
如果 i 不是基本类型,而是 List 等这种复杂类型,finally 中对它的改变,是会影响 return 的。因为对于复杂类型,保存的是它的地址。

正文完
 0