记一下一道关于finally的题
题目:
public class Test{
public int add(int a,int b){
try {
return a+b;
}
catch (Exception e) {
System.out.println("catch语句块");
}
finally{
System.out.println("finally语句块");
}
return 0;
}
public static void main(String argv[]){
Test test =new Test();
System.out.println("和是:"+test.add(9, 34));
}
}
结果是:
finally语句块
和是:43
为什么呢?首先,这个字符串的相加,涉及变量,所以底层是通过StringBuilder来进行的,所以先进入test.add(9, 34)。
然后,要个道理要知道,这是来自《The Java Tutorials》文档中的一段描述Finally关键字的话:
上面说到,finally块总是会在try块结束后执行,来保证finally块一定会执行,哪怕是有无法预测的异常抛出。但确实这个finally模块不仅仅是在异常控制中有所作用,它允许编程者在代码运行return,continue或者是break语句之前进行些其他的工作,像cleanup某些资源的代码。
但是!如果JVM(Java虚拟机)在执行try或者catch块的代码的时候退出了,那么finally块中的代码也就可能不会被执行到了,就像线程执行的时候被打断或者是直接被杀死这类的情况。
总结一下,实验的结论就是:finally块中的语句总是会在控制转移语句(break、continue、return等)执行之前执行!除非是遇到JVM退出的情况,finally块中的内容才不会被执行。
所以,这里在要执行try中的return之前,先去执行了finally中的打印语句,就有了这样的输出。
再来看两个特殊的例子
public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
} public static int beforeFinally(){
int a = 0;
try{
a = 1;
return a;
}finally{
a = 2;
}
}
}
/**output:
1
*/
从结果上看,貌似`finally` 里的语句是在`return` 之后执行的,其实不然,实际上`finally` 里的语句是在在`return` 之前执行的。那么问题来了,既然是在之前执行,那为什么`a` 的值没有被覆盖了?
实际过程是这样的:当程序执行到try{}语句中的return方法时,它会干这么一件事,将要返回的结果存储到一个临时栈中,然后程序不会立即返回,而是去执行finally{}中的程序, 在执行`a = 2`时,程序仅仅是覆盖了a的值,但不会去更新临时栈中的那个要返回的值 。执行完之后,就会通知主程序“finally的程序执行完毕,可以请求返回了”,这时,就会将临时栈中的值取出来返回。这下应该清楚了,要返回的值是保存至临时栈中的。
再来看一个例子,稍微改下上面的程序:
public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
} public static int beforeFinally(){
int a = 0;
try{
a = 1;
return a;
}finally{
a = 2;
return a;
}
}
}
/**output:
2
*/
在这里,finally{}里也有一个return,那么在执行这个return时,就会更新临时栈中的值。同样,在执行完finally之后,就会通知主程序请求返回了,即将临时栈中的值取出来返回。故返回值是2。
记一下一道关于finally的题的更多相关文章
- 洛谷P2918 [USACO08NOV]买干草(一道完全背包模板题)
题目链接 很明显的一道完全背包板子题,做法也很简单,就是要注意 这里你可以买比所需多的干草,只要达到数量就行了 状态转移方程:dp[j]=min(dp[j],dp[j-m[i]]+c[i]) 代码如下 ...
- 又一道区间DP的题 -- P3146 [USACO16OPEN]248
https://www.luogu.org/problemnew/show/P3146 一道区间dp的题,以区间长度为阶段; 但由于要处理相邻的问题,就变得有点麻烦; 最开始想了一个我知道有漏洞的方程 ...
- [真题] 一道 vsftp 运维题
一道 vsftp 运维题 一.前言 在 V 站上凑巧看到了好友发的求助帖,五天时间一个理他的都没有.哈哈哈~ 废话不多说,我们来试试. 二.题目 这里我们假设存在这样的场景: 网络内有普通用户 ade ...
- QDUOJ 一道简单的数据结构题 栈的使用(括号配对)
一道简单的数据结构题 发布时间: 2017年6月3日 18:46 最后更新: 2017年6月3日 18:51 时间限制: 1000ms 内存限制: 128M 描述 如果插入“+”和“1”到 ...
- 记一道有意思的算法题Rotate Image(旋转图像)
题出自https://leetcode.com/problems/rotate-image/ 内容为: You are given an n x n 2D matrix representing an ...
- 记一道CTF隐写题解答过程
0x00 前言 由于我是这几天才开始接触隐写这种东西,所以作为新手我想记录一下刚刚所学.这道CTF所需的知识点包括了图片的内容隐藏,mp3隐写,base64解密,当铺解密,可能用到的工具包括bin ...
- 记一道C语言编程题(C语言学习笔记)
题目如下 解答如下 #include <stdio.h> #include<math.h> double Mysqrt(double n) { return sqrt(n); ...
- hihocoder第220周-一道拧巴的题
一.220周 题目链接 问题描述 键盘上有N个数字按键,每个按键只能按一次,每次可以按下多个键,请输出所有可能的按键情况. 输入一个整数N(N在1~8之间),输出全部的按键可能.例如:输入3,输出为 ...
- Convex 一道阿姆斯特朗回旋好题
2001年5月8日,阿姆斯特朗(Armstrong, 1929-2013) 教授发明了一种名为“阿姆斯特朗回旋加速喷气式阿姆斯特朗加密”的加密算法,算法从未公开,直至2013阿姆斯特朗教授逝世后,其生 ...
随机推荐
- hdu 1106 排序 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1106 这个题目一开始以为是水题,就想着用来轻松轻松,谁知道改得我想吐!! 除了discuss 中的数据 ...
- multi_socket
threading_test.py #threading #为什么在命令行可以执行,F5不能执行 #线程处理能导致同步问题 from socketserver import TCPServer,Thr ...
- jni中c代码调用java代码
原理是使用反射的机制 java中反射的例子: Class<?> forName = Class.forName("com.example.ndkcallback.DataProv ...
- weex 打包apk
安装 weexpack weexpack create my-project //创建项目 cd my-project cnpm install //安装依赖 npm start //运行项目 ...
- 九、myeclipse开发背景保护色设置
window->preferences->Editors->Text Editors->Background color 背景颜色向你推荐: 色调:85.饱和度:1 2 3.亮 ...
- 四、mysql数据常用命令
1.显示mysql中所有数据库的名称,show databases; 2.访问某个数据库,use database_name; 3.显示当前数据库中所有表的名称,show tables; 4.查看当前 ...
- eclipse编辑窗口不见了(打开左边的java、xml文件,中间不会显示代码)
转自:https://blog.csdn.net/u012062810/article/details/46729779?utm_source=blogxgwz4 1. windows-->re ...
- 2 pyspark学习----基本操作
1 spark的python环境部署可以参照上面一篇哟.http://www.cnblogs.com/lanjianhappy/p/8705974.html 2 pyspark的基本操作. # cod ...
- jquery的on()绑定无效的方式
on前面的元素也必须在页面加载的时候就存在于dom里面.动态的元素或者样式等,可以放在on的第二个参数里面 jQuery on()方法是官方推荐的绑定事件的一个方法.使用 on() 方法可以给将来动态 ...
- JSONObject put List<Double> 后转化为String问题的解决办法
//原代码 JSONObject powerCurveJsonObj = new JSONObject(); powerCurveJsonObj.put("test",[0.5, ...