先看一段代码:

@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返回结果执行先后详解的更多相关文章

  1. Oracle执行计划详解

    Oracle执行计划详解 --- 作者:TTT BLOG 本文地址:http://blog.chinaunix.net/u3/107265/showart_2192657.html --- 简介:   ...

  2. ping命令执行过程详解

    [TOC] ping命令执行过程详解 机器A ping 机器B 同一网段 ping通知系统建立一个固定格式的ICMP请求数据包 ICMP协议打包这个数据包和机器B的IP地址转交给IP协议层(一组后台运 ...

  3. mysql中SQL执行过程详解与用于预处理语句的SQL语法

    mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...

  4. [转]Oracle执行计划详解

    Oracle执行计划详解 --- 作者:TTT BLOG 本文地址:http://blog.chinaunix.net/u3/107265/showart_2192657.html --- 简介:   ...

  5. MySQL 语句执行过程详解

    MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...

  6. MySQL 执行计划详解

    我们经常使用 MySQL 的执行计划来查看 SQL 语句的执行效率,接下来分析执行计划的各个显示内容. EXPLAIN SELECT * FROM users WHERE id IN (SELECT ...

  7. MySQL性能分析, mysql explain执行计划详解

    MySQL性能分析 MySQL性能分析及explain用法的知识是本文我们主要要介绍的内容,接下来就让我们通过一些实际的例子来介绍这一过程,希望能够对您有所帮助. 1.使用explain语句去查看分析 ...

  8. Hadoop MapReduce执行过程详解(带hadoop例子)

    https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...

  9. Hadoop学习之Mapreduce执行过程详解

    一.MapReduce执行过程 MapReduce运行时,首先通过Map读取HDFS中的数据,然后经过拆分,将每个文件中的每行数据分拆成键值对,最后输出作为Reduce的输入,大体执行流程如下图所示: ...

随机推荐

  1. php 定时执行任务

    之于是否控制,可以做到的,应借用第三个条件: config.php <?phpreturn 1;?> cron.phpignore_user_abort();//关掉浏览器,PHP脚本也可 ...

  2. ubuntu中vi在编辑状态下方向键不能用的解决

    ubuntu中vi在编辑状态下方向键不能用,还有回格键不能删除等,我们平时习惯的一些键都不能使用. 解决办法: 可以安装vim full版本,在full版本下键盘正常,安装好后同样使用vi命令. 安装 ...

  3. C++ 11 笔记 (三) : auto

    我真的不是标题党... 虽然大一上学期学C语言基础时就学了auto关键字了,而且还是跟static和register两个关键字打包学的,但是.. 猜的没错,C++11这货又给auto加新功能了,在 C ...

  4. Python 类 setattr、getattr、hasattr 的使用

    #coding=utf-8 class Employee: '所有员工的基类' empCount = 0 def __init__(self, name, salary): self.name = n ...

  5. Introduction to Gaussian Processes

    Introduction to Gaussian Processes Gaussian processes (GP) are a cornerstone of modern machine learn ...

  6. Essential Sublime Text Plugins

    Essential Sublime Text Plugins Add some killer tools to your arsenal. View them all at /repo/sublime ...

  7. Metasploit介绍

    Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估, 提供真正的安全风险情报.这些功能包括智能开发,密码审计 ...

  8. [ecmall]Ecmall 后台添加模板编辑区

    例如,想把品牌/index.php?app=brand页面做成可编辑的. 首先,找到后台admin\includes\menu.inc.php第61行 'template' => array( ...

  9. 配置.NET程序中最大HTTP并发连接数(默认为2)

    方式一:代码 ServicePointManager.DefaultConnectionLimit = 方式二:配置 <system.net> <connectionManageme ...

  10. 【CF】196 Div.2 D. Book of Evil

    显然这个图是一课树,看着题目首先联想到LCA(肯定是可以解的).但是看了一下数据大小,应该会TLE.然后,忽然想到一个前面做过的题目,大概是在一定条件下树中某结点旋转成为根后查询最长路径.结果灵感就来 ...