try与finally返回结果执行先后详解
先看一段代码:
@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;
}
执行结果:--------------------------
f1
f2
2
结果中可发现是在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");
}
执行结果:-----------------------------------
f1
f2
af1f2
结果中也有try块中返回结果的f1,也有finally块中返回结果的f2。那为何与上次的实验结果不同呢,注意到这次返回类型是对象类型StringBuilder,每次return都是在原来的返回
结果上append,而不是覆盖。这也就验证了try中return子函数并没有实际返回,而是将结果存入到一个内存中,而finally中的return也是操作这块内存,如果是基本类型,则直
接覆盖,如果是引用类型,则根据具体的操作来决定是覆盖还是修改。
try与finally返回结果执行先后详解的更多相关文章
- Oracle执行计划详解
Oracle执行计划详解 --- 作者:TTT BLOG 本文地址:http://blog.chinaunix.net/u3/107265/showart_2192657.html --- 简介: ...
- ping命令执行过程详解
[TOC] ping命令执行过程详解 机器A ping 机器B 同一网段 ping通知系统建立一个固定格式的ICMP请求数据包 ICMP协议打包这个数据包和机器B的IP地址转交给IP协议层(一组后台运 ...
- mysql中SQL执行过程详解与用于预处理语句的SQL语法
mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...
- [转]Oracle执行计划详解
Oracle执行计划详解 --- 作者:TTT BLOG 本文地址:http://blog.chinaunix.net/u3/107265/showart_2192657.html --- 简介: ...
- MySQL 语句执行过程详解
MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...
- MySQL 执行计划详解
我们经常使用 MySQL 的执行计划来查看 SQL 语句的执行效率,接下来分析执行计划的各个显示内容. EXPLAIN SELECT * FROM users WHERE id IN (SELECT ...
- MySQL性能分析, mysql explain执行计划详解
MySQL性能分析 MySQL性能分析及explain用法的知识是本文我们主要要介绍的内容,接下来就让我们通过一些实际的例子来介绍这一过程,希望能够对您有所帮助. 1.使用explain语句去查看分析 ...
- Hadoop MapReduce执行过程详解(带hadoop例子)
https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...
- Hadoop学习之Mapreduce执行过程详解
一.MapReduce执行过程 MapReduce运行时,首先通过Map读取HDFS中的数据,然后经过拆分,将每个文件中的每行数据分拆成键值对,最后输出作为Reduce的输入,大体执行流程如下图所示: ...
随机推荐
- 解决php的$美元符号与Zen Coding冲突问题
Zen Coding插件就不介绍了. 众所周知,安装了插件以后,输入$符号会被自动解析为相应的数字1.2.3... 作为一名PHP程序员,想要通过其定义一些自己常用的代码.却发现展开以后悲剧的发现$符 ...
- PHP 自 5.2 到 5.6 中新增的功能详解
截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在维护 [注] 的 PHP5.2, 其余的一半用户在使用 PHP5.3 [注].因为 PHP 那 ...
- yarn资源管理器高可用性的实现
资源管理器高可用性 . The ResourceManager (RM) is responsible for tracking the resources in a cluster, and sch ...
- C语言-06复杂数据类型-02字符串
#include <stdio.h> int main() { //char name[] = {'i', 't', 'c', 'H', 's', 't', '\0'}; char nam ...
- NULL, nil, Nil详解
原文地址:http://blog.csdn.net/wzzvictory/article/details/18413519 感谢原作者 作者:wangzz 原文地址:http://blog.cs ...
- UM_第三方登录
参考官方文档(http://dev.umeng.com/social/ios/detail-share#7), 做出以下总结. 第三方登录主要用于简化用户登录流程,通过用户拥有的微博.QQ.微信等第三 ...
- bzoj 1815: [Shoi2006]color 有色图 置换群
1815: [Shoi2006]color 有色图 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 136 Solved: 50[Submit][Stat ...
- 【技术贴】note8 N5100刷机 双清 落雨
双清模式:开机键 + [音量+] + HOME键 刷机模式:开机键 + [音量- ]+ HOME键 1.双清步骤: 关机时.长按音量上键+home键+开机键,直到进入recovery模式,然后选择wi ...
- iOS开发网络篇—多线程断点下载
iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...
- ANDROID_MARS学习笔记_S04_006_用获取access_token,access_token_secrect
一.代码流程 1.MainActivity会开启PrepareRequestTokenActivity 2.PrepareRequestTokenActivity会根据配置文件的CONSUMER_KE ...