博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
try与finally返回结果执行先后详解
阅读量:5355 次
发布时间:2019-06-15

本文共 2005 字,大约阅读时间需要 6 分钟。

先看一段代码:

@Test	public void test1(){		System.out.println(testf1());	}		int testf1()      {          int x = 1;          try          {              return x;          }          finally          {              ++x;              System.out.println(x);        }      }
执行结果:----------------------------

2

1

为什么最后的返回结果不是2呢?明明finally已经对x+1的运行已经执行了才返回。

讲上面程序修改下,在finally块里也加上return。

@Test	public void test2(){		System.out.println(testf2());	}		int testf2()      {          int x = 1;          try          {              return x;          }          finally          {              ++x;              System.out.println(x);            return x;        }      }
返回结果:------------------------

2

2

很奇怪,改完之后输出结果变成了2。

再将程序修改下:

@Test	public void test3(){		System.out.println(test8());	}		public int test8(){		try{			return f1();		}finally{			return f2();		}	}		public int f1(){		System.out.println("f1");		return 1;	}		public int f2(){		System.out.println("f2");		return 2;	}
执行结果:--------------------------

f1f22
结果中可发现是在try块里的return语句先执行,但执行了return之后,子函数并没有立即返回,而是继续执行了finally块里的语句并return。最后的返回结果采取的是

finally块里的return结果。

猜想:子函数在try中return时将返回结果压入栈中,而在finally中再次return时,由于返回类型是基本类型,直接覆盖了上次的返回结果。这样子函数调用返回给上层函数的结果

就是最后一次finally中return的结果。为了验证这个猜想,继续修改程序,代码如下:

@Test	public void test9(){		StringBuilder sb = new StringBuilder("a");		System.out.println(test9(sb));	}		public StringBuilder test9(StringBuilder sb){		try{			return f1(sb);//先执行,将结果压入栈中		}finally{			return f2(sb);//后执行,再将前一次结果覆盖		}	}	private StringBuilder f2(StringBuilder sb) {		System.out.println("f2");		return sb.append("f2");	}	private StringBuilder f1(StringBuilder sb) {		System.out.println("f1");		return sb.append("f1");	}

执行结果:-----------------------------------
f1f2af1f2

结果中也有try块中返回结果的f1,也有finally块中返回结果的f2。那为何与上次的实验结果不同呢,注意到这次返回类型是对象类型StringBuilder,每次return都是在原来的返回

结果上append,而不是覆盖。这也就验证了try中return子函数并没有实际返回,而是将结果存入到一个内存中,而finally中的return也是操作这块内存,如果是基本类型,则直

接覆盖,如果是引用类型,则根据具体的操作来决定是覆盖还是修改。

转载于:https://www.cnblogs.com/marcotan/p/4256903.html

你可能感兴趣的文章
网页中插入透明Flash的方法和技巧
查看>>
动态内存申请函数选择(realloc、malloc 、alloca、 calloc)
查看>>
获取元素属性get_attribute
查看>>
视觉设计师的进化
查看>>
Python/jquery
查看>>
【BZOJ】【2132】圈地计划
查看>>
Lua 语言基本语法
查看>>
ARM 的Thumb状态测试
查看>>
windows下读取utf-8文件
查看>>
apache 启动不了的排查方法
查看>>
Java有没有goto?
查看>>
(转)makefile 的用法
查看>>
求不相邻金币相加和的最大值--动态规划1
查看>>
[转][osg]探索未知种族之osg类生物【目录】
查看>>
四十九. Zabbix报警机制 、 Zabbix进阶操作 、 监控案例
查看>>
元类中__new__ 与 __init__的区别--day27
查看>>
占小狼的简书博客
查看>>
struts2__action执行顺序
查看>>
php异常处理
查看>>
[xampp] /usr/bin/env: php: No such file or directory
查看>>