Try-Catch-Finally代码块中的return

测试类的原型是这样子的

public class TryCatchFinallyToReturn {

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

    public static int test() {
        try {
            System.out.println("try block.");
            throwMethod();
            return 1;
        } catch(Exception e) {
            System.out.println("catch block.");
            return 2;
        } finally {
            System.out.println("finally");
            return 3;
        }
    }

    public static void throwMethod() throws Exception {
        
    }

}

可以看到finally代码块整个大括号都出现了警告了,

finally block does not complete normally

说明finally{}中出现return是不合适的。

强行运行一下,结果是这样的(结果1

try block.
finally block.
3

通过断点追踪,try{}中的return 1已经运行到了,但是try{}正常运行结束后,finally{}必须要被执行

最后所以真正的返回值是3

变更一下测试原型,测试一下出现异常的情况

    public static void throwMethod() throws Exception {
        System.out.println("throw.");
        throw new Exception();
    }

运行一下(结果2

try block.
throw.
catch block.
finally block.
3

异常被捕获到了catch{}中的return 2确保了运行,但是返回值依然是finall{}中的return 3。

同样的,通过断点追踪发现return 2也被运行到了,但是被return 3覆盖

最后删除finally{} 中的return 3

        } finally {
            System.out.println("finally block.");
        }

运行一下通过调整throwMethod方法,分别测试一下正常情况和异常情况(结果3)(结果4

try block.
finally block.
1
try block.
throw.
catch block.
finally block.
2

返回值正确了。

现在可以得到4个结论

A、运行时发生异常的那条语句再也没有机会运行到了,原因是异常被catch()捕获到,程序流程进入了catch{}

这点可以通过结果2看到,断点没有运行到return 1

B、无论try{}还是catch{}发生了什么,finally{}中的语句一定会运行到

这点可以通过结果1234看到,"finally block."怎么样都是打印出来的

C、当try{}或是catch{}发生return时,方法并不是立即返回的,而是等finally{}执行完毕后,才返回

这点可以通过结果34看到,在打印结果"1"或"2"的前一行,"finally block."被打印出来了

D、如果设计不当,使finally{}中存在return语句,那么执行当finally{return}时,方法会直接返回,finally{}执行之前预定需要返回的返回值,会被覆盖掉

这点可以通过结果12看到,返回值都是finally里的3而不是try里的1或catch里的2。

C、D可以如此理解,没有返回语句的finally{}比较本分,try{}、catch{}顾及到语言限定,在返回前给了finally{}运行的机会,finally运行完毕后返回正确的值;

但编码使另finally{}中出现返回语句,那么finally{}就像是一个过河拆桥的人,利用try{}或是catch{}给的机会,执行了自己的返回语句,让方法直接结束,try{return}或catch{return}再也没有机会返回了。

原文地址:https://www.cnblogs.com/deolin/p/6863444.html