return & finally 执行顺序 这是我读到的最合理的解释
新词:return [expression] 栈顶元素 局部变量的快照
java方法是在栈幀中执行,栈幀是线程私有栈的单位,执行方法的线程会为每一个方法分配一小块栈空间来作为该方法执行时的内存空间,栈幀分为三个区域:
1. 操作数栈,用来保存正在执行的表达式中的操作数,数据结构中学习过基于栈的多项式求值算法,操作数栈的作用和这个一样
2. 局部变量区,用来保存方法中使用的变量,包括方法参数,方法内部声明的变量,以及方法中使用到的对象的成员变量或类的成员变量(静态变量),最后两种变量会复制到局部变量区,因此在多线程环境下,这种变量需要根据需要声明为volatile类型
3. 字节码指令区,这个不用解释了,就是方法中的代码翻译成的指令
关于return与finally
有了上面的预备知识我们就不难理解return和finally之间的关系了,我们要记住的就是在return [expression];
这里跟在return后面的表达式,
返回的是return指令执行的时刻,操作数栈顶的值,不管expression是一个怎样的表达式,究竟做了些什么工作,对于return指令来说都不重要,他只负责把操作数栈顶的值返回。
而return expression是分成两部分执行的:
执行:expression;
执行:return指令;
例如:return x+y;
这句代码先执行x+y,再执行return;首先执行将x以及y从局部变量区复制到操作数栈顶的指令,然后执行加法指令,这个时候结果x+y的值会保存在操作数栈的栈顶,最后执行return指令,返回操作数栈顶的值。
对于return x;先执行x,x也是一个表达式,这个表达式只有一个操作数,会执行将变量x从局部变量区复制到操作数栈顶的指令,然后执行return,返回操作数栈顶的值。因此return x实际返回的是return指令执行时,x在操作数栈顶的一个快照或者叫副本,而不是x这个值。
而当存在finally语句块的时候,首先我们知道,finally语句是一定会执行,但他们的执行顺序是怎么样的呢?他们的执行顺序如下:
1、执行:expression,计算该表达式,结果保存在操作数栈顶;
2、执行:操作数栈顶值(expression的结果)复制到局部变量区作为返回值;
3、执行:finally语句块中的代码;
4、执行:将第2步复制到局部变量区的返回值又复制回操作数栈顶;
5、执行:return指令,返回操作数栈顶的值;
我们可以看到,在第一步执行完毕后,整个方法的返回值就已经确定了,由于还要执行finally代码块,因此程序会将返回值暂存在局部变量区,腾出操作数栈用来执行finally语句块中代码,等finally执行完毕,再将暂存的返回值又复制回操作数栈顶。所以无论finally语句块中执行了什么操作,都无法影响返回值,所以试图在finally语句块中修改返回值是徒劳的。因此,finally语句块设计出来的目的只是为了让方法执行一些重要的收尾工作,而不是用来计算返回值的。
所以在finally中更改返回值是无效的,因为它只是更改了操作数栈顶端复制到局部变量区的快照,并不能真正的更改返回值,但是如果在
finally中使用return的话则是会将新的操作数栈的顶端数据返回,而不是之前复制到局部变量区用作返回内容快照的值返回,所以这样是可以返回的,同样的在cathch语句块里
也是这样,只有重新出现了return才有可能更改返回值。
感谢大佬:
作者:烟火HL
来源:CSDN
原文:https://blog.csdn.net/sinat_22594643/article/details/80509266
版权声明:本文为博主原创文章,转载请附上博文链接!
return & finally 执行顺序 这是我读到的最合理的解释的更多相关文章
- 我敢说你不一定完全理解try 块,catch块,finally 块中return的执行顺序
大家好,今天我们来讲一个笔试和面试偶尔都会问到的问题,并且在工作中不知道原理,也会造成滥用. 大家可能都知道,try 块用来捕获异常,catch块是处理try块捕获的异常,finally 块是用来关闭 ...
- java中finally和return的执行顺序
注意:return的位置... 从这几个例子中可以看到,如果try之前没有有条件的return,则try..catch..finally语句块中的语句都是顺序执行(如果try中或者catch中 有re ...
- JAVA中try、catch、finally带return的执行顺序总结
异常处理中,try.catch.finally的执行顺序,大家都知道是按顺序执行的.即,如果try中没有异常,则顺序为try→finally,如果try中有异常,则顺序为try→catch→final ...
- 理清Java中try-catch-finally带return的执行顺序
前言:try-catch-finally带return和异常时,它们之间执行顺序问题是留下来的一个小疑问,今天搞清楚它们 第一种情况:无异常 //1.try-catch-finally都带有retur ...
- go defer、return的执行顺序
一.一个函数中多个defer的执行顺序 defer 的作用就是把defer关键字之后的函数执行压入一个栈中延迟执行,多个defer的执行顺序是后进先出LIFO,也就是先执行最后一个defer,最后执行 ...
- try、catch、finally、return的执行顺序
1. 不管有没有异常,finally里面的语句都会执行 2. 当try和catch中有返回语句时,finally里面的语句还是会执行 3. 如果finally里面没有return语句,try和catc ...
- java中的try-catch-finally中的return的执行顺序
在这里看到了try catch finally块中含有return语句时程序执行的几种情况,但其实总结的并不全,而且分析的比较含糊.但有一点是可以肯定的,finally块中的内容会先于try中的ret ...
- java中异常处理finally和return的执行顺序
根据个人亲自测试,得出如下结果: 1.try,catch中有没有return,finnally都会执行,而且是先执行try,catch后,最后执行finnally语句: 2.如果finnally中有r ...
- Python异常捕捉try except else finally有return时执行顺序探究
转载自 https://www.cnblogs.com/JohnABC/p/4065437.html 学习python或者其他有异常控制的编程语 言, 大家很有可能说try except finall ...
随机推荐
- [rtsp]海康IPC监控摄像头远程外网监控配置(DDNS)
本来这个DDNS服务正是我想要的,但是配置了之后海康提示不再提供这个服务了,以后统一使用萤石云了,看来有必要去学习下萤石开放平台的api,看都提供哪些服务. 海康威视网络摄像机出厂的默认IP地 ...
- android:Android中用文件初始化sqlite数据库(zz)
很多时候在应用安装初始化时,需要创建本地数据库,同时为数据库添加数据,之后再从数据库中读取数据. 这里有2个思路 1.先在本地创建一个能支持android使用的sqlite数据库文件,启动时, ...
- Linux命令行烧录树莓派镜像至SD卡
首先下载镜像压缩包 验证压缩包的未被串改 1 sha1sum 2013-09-25-wheezy-raspbian.zip 对此命令的输出结果和官网给出的SHA-1 Checksum进行比对,如果一致 ...
- 每天一个linux命令(14):head命令
1.命令简介 head (head) 用来显示档案的开头至标准输出中.如果指定了多于一个文件,在每一段输出前会给出文件名作为文件头.如果不指定文件,或者文件为"-",则从标准输入读 ...
- Fiddler抓包_重定向AutoResponder
1. 文件及图片替换(Enable rules) 目的:允许从本地返回文件,代替服务器响应,而不用将文件发布到服务器[可用正式环境验证本地文件] 步骤一:抓页面http://ir.baidu.com/ ...
- (原)tensorflow使用eager在mnist上训练的简单例子
转载请注明出处: https://www.cnblogs.com/darkknightzh/p/9989586.html 代码网址: https://github.com/darkknightzh/t ...
- mongodb连接配置实践
之前百度,google了很多,发现并没有介绍mongodb生产环境如何配置的文章, 当时想参考下都不行, 所以写篇文章,大家可以一块讨论下. 1. MongoClientOptions中的连接池配置: ...
- Centos7.4别名设置提高工作效率
一.打开 .bashrc文件 1.位置:~(cd ~)目录下 2.cat .bashrc 原文件内容如下: # .bashrc # User specific aliases and function ...
- CentOS 7 yum nginx MySQL PHP7 简易环境搭建(精)
用centos自带的yum源来安装nginx,mysql和php,超级方便,省去编译的麻烦,省去自己配置的麻烦,还能节省非常多的时间. 我们先把yum源换成国内的阿里云镜像源(当然不换也可以),先备份 ...
- [k8s]debug模式启动集群&k8s常见报错集合(on the fly)
debug模式启动-支持sa 集群内(pod访问api)使用443加密 no1 no2 安装flanneld kubelet/kube-proxy m1 安装etcd/ api/contruller/ ...