php try finally,try-catch-finally的执行顺序是什么

try-catch-finally的执行顺序是:1、不管有没有出现异常,finally块中的代码都会执行;2、当try和catch中有return时,finally仍然会执行;3、finally是在return后面的表达式运算后执行的。

abdb6d6bfa055a6418a6497b2ed5e957.png

try catch finally 执行顺序结论

1、不管有没有出现异常,finally块中代码都会执行;

2、当try和catch中有return时,finally仍然会执行;

3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;

4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

测试案例1public class FinallyTest

{

public static void main(String[] args) {

System.out.println(new FinallyTest().test());;

}

static int test()

{

int x = 1;

try

{

x++;

return x;

}

finally

{

++x;

}

}

}

结果是2

分析:

在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。

在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,

因此,即使finally中对变量x进行了改变,但是不会影响返回结果。

测试案例2public static int testBasic(){

int i = 1;

try{

i++;

System.out.println("try block, i = "+i);

}catch(Exception e){

i ++;

System.out.println("catch block i = "+i);

}finally{

i = 10;

System.out.println("finally block i = "+i);

}

return i;

}

没错,会按照顺序执行,先执行try内代码段,没有异常的话进入finally,最后返回,那么输出如下:try block, i = 2

finally block i = 10

main test i = 10

测试案例3public static int testBasic(){

int i = 1;

try{

i++;

System.out.println("try block, i = "+i);

return i;

}catch(Exception e){

i ++;

System.out.println("catch block i = "+i);

return i;

}finally{

i = 10;

System.out.println("finally block i = "+i);

}

}

输出结果是:try block, i = 2

finally block i = 10

main test i = 2

代码顺序执行从try到finally,由于finally是无论如何都会执行的,所以try里的语句并不会直接返回。在try语句的return块中,return返回的引用变量并不是try语句外定义的引用变量i,而是系统重新定义了一个局部引用i’,这个引用指向了引用i对应的值,也就是2,即使在finally语句中把引用i指向了值10,因为return返回的引用已经不是i,而是i’,所以引用i的值和try语句中的返回值无关了。

但是,这只是一部分,如果把i换成引用类型而不是基本类型呢,来看看输出结果怎样,示例如下:public static List testWrap(){

List list = new ArrayList<>();

try{

list.add("try");

System.out.println("try block");

return list;

}catch(Exception e){

list.add("catch");

System.out.println("catch block");

return list;

}finally{

list.add("finally");

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

}

}

打印结果如下:try block

finally block

main test i = [try, finally]

可以看到,finally里对list集合的操作生效了,这是为什么呢。我们知道基本类型在栈中存储,而对于非基本类型是存储在堆中的,返回的是堆中的地址,因此内容被改变了。

好了,现在我们在finally里加一个return,看看语句是从哪里返回的。public static int testBasic(){

int i = 1;

try{

i++;

System.out.println("try block, i = "+i);

return i;

}catch(Exception e){

i ++;

System.out.println("catch block i = "+i);

return i;

}finally{

i = 10;

System.out.println("finally block i = "+i);

return i;

}

}

输出结果如下:try block, i = 2

finally block i = 10

main test i = 10

可以看到,是从finally语句块中返回的。可见,JVM是忽略了try中的return语句。但IDE中会对finally中加的return有黄色警告提示,这是为什么呢,在try里加入一行会执行异常的代码,如下:public static int testBasic(){

int i = 1;

try{

i++;

int m = i / 0 ;

System.out.println("try block, i = "+i);

return i;

}catch(Exception e){

i ++;

System.out.println("catch block i = "+i);

return i;

}finally{

i = 10;

System.out.println("finally block i = "+i);

return i;

}

}

打印结果如下:catch block i = 3

finally block i = 10

main test i = 10

可以看到,因为finally中有return语句,try、catch中的异常被消化掉了,屏蔽了异常的发生,这与初期使用try、catch的初衷是相违背的,因此编译器也会提示警告。

那如果在finally中有异常发生,会对try、catch中的异常有什么影响呢?public static int testBasic(){

int i = 1;

try{

i++;

Integer.parseInt(null);

System.out.println("try block, i = "+i);

return i;

}catch(Exception e){

String.valueOf(null);

System.out.println("catch block i = "+i);

return i;

}finally{

i = 10;

int m = i / 0;

System.out.println("finally block i = "+i);

}

}

这里我们在try、catch里强行加上异常语句,打印结果如下:Exception in thread “main” java.lang.ArithmeticException: / by zero

at tryandcatch.TryAndCatch.testBasic(TryAndCatch.java:25)

at tryandcatch.TryAndCatch.main(TryAndCatch.java:45)

这个提示表示的是finally里的异常信息,也就是说一旦finally里发生异常,try、catch里的异常信息即被消化掉了,也达不到异常信息处理的目的。

总结以上测试:

1、finally语句总会执行

2、如果try、catch中有return语句,finally中没有return,那么在finally中修改除包装类型和静态变量、全局变量以外的数据都不会对try、catch中返回的变量有任何的影响(包装类型、静态变量会改变、全局变量)

3、尽量不要在finally中使用return语句,如果使用的话,会忽略try、catch中的返回语句,也会忽略try、catch中的异常,屏蔽了错误的发生

4、finally中避免再次抛出异常,一旦finally中发生异常,代码执行将会抛出finally中的异常信息,try、catch中的异常将被忽略

所以在实际项目中,finally常常是用来关闭流或者数据库资源的,并不额外做其他操作。

更多相关知识,请访问 PHP中文网!!

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值