关于trycatchfinal返回值问题
来源:互联网 发布:打条码软件 编辑:程序博客网 时间:2024/06/06 00:01
And.He
Miracles happen every day.
关于try...catch...finally中return的疑惑
关于try...catch...finally里面的return一直是面试的一个热门考点。无非就分以下几个情况:
1、当有finally语句并且try中有return,在执行到return(还未执行)的时候,会先执行finally里面的内容,然后再执行行try中的return。
package com.and.java.demo;public class 测试 { public static void main(String[] args) { System.out.println(new 测试().test()); } public String test() { try { System.out.println("try{...}"); return "try"; } catch (Exception e) { System.out.println("catch{...}"); return "catch"; } finally { System.out.println("finally{...}"); } }}
输出:
try{...}finally{...}try
2、在1的基础上,如果finally里面也有return语句,则try代码块中的return被屏蔽(不执行),即在try中遇到return的时候,会先执行finally里面的内容(包括finally里面的return语句)。
package com.and.java.demo;public class 测试 { public static void main(String[] args) { System.out.println(new 测试().test()); } public String test() { try { System.out.println("try{...}"); return "try"; } catch (Exception e) { System.out.println("catch{...}"); return "catch"; } finally { System.out.println("finally{...}"); return "finally"; } }}
输出:
try{...}finally{...}finally
遇到的问题:
这两种情况想必大家已经掌握。但是还有一种情况,也是我不能理解的地方。一般情况下,在finally里面作一些数据的关闭操作(比如文件,输入/输出流,数据库的关闭),试想一下,要是我们在finally里面对要返回的值进行修改,那会反应到最终的结果上去吗?(因为从上面的讲解可以知道,当try里面有return的时候,它不会立刻执行,会先执行finally里面的内容,然后再执行return)。
package com.and.java.demo;public class 测试 { public static void main(String[] args) { System.out.println(new 测试().test()); } public String test() { String result = ""; try { result = "try"; return result; } catch (Exception e) { result = "catch"; return result; } finally { result = "finally"; } }}
试想一下,它会输出"try" 呢还是"finally"呢?
输出:
try
确实只输出try,但是我们在finally里面是改变了result的值呀?
再进一步改进,判断finally里面的赋值语句是否执行
package com.and.java.demo;public class 测试 { public static void main(String[] args) { System.out.println(new 测试().test()); } public String test() { String result = ""; try { result = "try"; return result; } catch (Exception e) { result = "catch"; return result; } finally { System.out.println("t1->"+result); result = "finally"; System.out.println("t2->"+result); } }}
输出:
t1->tryt2->finallytry
从输出结果可以看出,finally里面的赋值语句是执行了的,但是在return结果中怎么就没变呢?(目前暂时研究到这个地步,仍没搞明白,还望各位高手指点)
» 下一篇:iOS学习笔记之NSString
int 也属于值引用的,try,catch,finally是三个不用的作用域,执行try里面的result = "try",然后执行finally里面的result = "finally",其实这个时候try里面的result的值并没有改变,它只是将它的值copy给到了finally,是里面的一个临时变量而已,所以finally里的操作对try里面的值没有改变的,而执行完finally里的操作后,finally里的result就被丢弃了,等着回收
public
class
测试 {
int
i =
0
;
public
static
void
main(String[] args) {
测试 t =
new
测试();
System.out.println(t.i);
System.out.println(t.test());
System.out.println(t.i);
}
public
int
test() {
try
{
i =
1
;
return
i;
}
catch
(Exception e) {
i = -
1
;
return
i;
}
finally
{
i =
2
;
}
}
}
public
class
测试 {
public
static
void
main(String[] args) {
System.out.println(
new
测试().test());
}
public
String test() {
String result =
""
;
try
{
result =
"try"
;
return
result;
}
catch
(Exception e) {
result =
"catch"
;
return
result;
}
finally
{
System.out.println(
"t1->"
+result);
result =
"finally"
;
System.out.println(
"t2->"
+result);
//在这里加上一行,就会看到返回值变了
return
result;
}
}
}
try{
s ="a";
return s;
}catch{
s="b";
return s;
}finally{
s ="c";
}
结构中虚拟机的处理方式是 在try 语句中 会把return的变量引用的对象存入一个局部变量表(虚拟机可见,程序不可见)里面,然后进入finally语句块中,如果finally没有return语句,则处理finally的语句,这个时候finally的变量S和Try中的变量S是同一个变量,所以S的值是改变的。但是finally执行结束之后,return 返回值的时候,会把复制的结果返回
例如下面的代码
public class TryCatchFinally {
@SuppressWarnings("finally")
public Test test() {
Test t = new Test();
try {
t.setS("try");
return t;
} catch (Exception e) {
//result = "catch";
return t;
} finally {
t = new Test();
t.setS("finallyu");
//return result;
}
}
}
class Test{
public String s ="a";
public void setS(String s){
this.s = s;
}
}
其实还是返回的 Test.getS() 结果为 try
C#的finally里面,不允许return的
package com.and.java.demo;
public class 测试 {
public static void main(String[] args) {
System.out.println(new 测试().test());
}
public String test() {
try {
System.out.println("try{...}");
return "try";
} catch (Exception e) {
System.out.println("catch{...}");
return "catch";
} finally {
System.out.println("finally{...}");
return "finally";
}
}
}
分析以上代码,先执行try中的return语句,该语句会将"try"对象的引用保存到CPU的寄存器中,该语句的跳转指令被屏蔽。然后执行finally中的return语句,该语句会将“finally”对象的引用保存到CPU的寄存器中(覆盖了try的),然后执行跳转指令。所以返回的是指向"finally"的指针,但是try中的return的确执行了。
package com.and.java.demo;
public class 测试 {
public static void main(String[] args) {
System.out.println(new 测试().test());
}
public String test() {
String result = "";
try {
result = "try";
return result;
} catch (Exception e) {
result = "catch";
return result;
} finally {
result = "finally";
}
}
}
分析以上代码,先执行try中的return语句(try中的语句总是先执行),该语句会将"try"对象的引用保存到CPU的寄存器中,然后执行finllay语句,该语句会将result局部变量的值重新定位成指向"finally"对象。最后执行跳转指令,因为CPU寄存器中保存的是“try”的引用,所以返回值是"try"的引用。
· Windows 10周年更新迎神秘累积更新:还是没有更新日志
· OpenSSL团队成员将于9月拜访中国:经过上海/深圳/北京三地
· Uber新CEO致老东家公开信:与你们共事是我的荣幸
· Google地图想要帮助用户在25个新城市找到停车位
· NASA将在明年上半年发射InSight火星探测器
» 更多新闻...
· 写给立志做码农的大学生
· 架构腐化之谜
· 学会思考,而不只是编程
· 编写Shell脚本的最佳实践
我只是坚持我的兴趣。
有所专而多能,精于一而博学。
- 个人资料
- 访问:620521次
- 积分:4873
- 等级:
- 排名:第5919名
- 原创:39篇
- 转载:108篇
- 译文:4篇
- 评论:103条
kavensu
- 友情链接
- Parse
Strikingly(傻瓜式网页设计)
- 文章搜索
- 文章分类
- Android(45)
- Android 数据存储(2)
- Android 自定义UI控件(6)
- Android 进程与线程(2)
- Android 多媒体(3)
- Android 编程规范(2)
- PHP(1)
- Java(19)
- Web 开发(4)
- 随笔(3)
- 创业(1)
- 软件安装及配置(9)
- 有启发的时文(5)
- 算法(9)
- 计算机网络(9)
- Epub(3)
- 其他(6)
- 操作系统(3)
- 编译原理(1)
- UML(1)
- 笔试面试题(6)
- C#开发(3)
- JavaScrip & Node.js(5)
- Git(1)
- 文章存档
- 2016年05月(1)
- 2016年04月(1)
- 2015年01月(1)
- 2014年01月(10)
- 2013年11月(1)
- 阅读排行
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)(133862)
- 邮件协议POP3/IMAP/SMTP服务的区别(57078)
- 【使用线程池的好处】多线程的环境中,尽量采用线程池(25782)
- TableLayout和TableRow的使用(18333)
- C#中SQL语句的参数写法(17579)
- 使用HttpClient通过POST方式发送XML,使用TCP/IP Monitor观察数据(16685)
- javascript 对象数组排序(15445)
- node.js常用模块(15132)
- onContextItemSelected 与 onMenuItemSelected 的那些事(14486)
- OSI的七层模型,网线,网卡,集线器,交换机,路由器分别工作在七层模型中的哪一层?(13713)
- 评论排行
- 2013网易技术类笔试题(java开发方向+移动平台开发)(30)
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)(28)
- onContextItemSelected 与 onMenuItemSelected 的那些事(6)
- 使用ActivityGroup时,在Activity中显示对话框出现的问题(5)
- 条码扫描二维码扫描——ZXing android(4)
- 网页分页数据抓取的几种方式(3)
- 网上下载图片并保持到SD卡中+读取SD卡中的图片(2)
- 【使用线程池的好处】多线程的环境中,尽量采用线程池(2)
- Android中Fragment的应用(android官方教程完美翻译)(2)
- 用点画分隔线(2)
- 推荐文章
- * CSDN日报20170828——《4个方法快速打造你的阅读清单》
- * CSDN博客模板调查问卷
- * 秒杀系统的一点思考
- * TCP网络通讯如何解决分包粘包问题
- * 技术与技术人员的价值
- * GitChat·人工智能 | 除了深度学习,机器翻译还需要啥?
- 最新评论
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
口袋本人: @mochounv:会执行的,建议你去实践一下。
- 【使用线程池的好处】多线程的环境中,尽量采用线程池
weixin_38310495: 666
- 【使用线程池的好处】多线程的环境中,尽量采用线程池
health7788: 厉害了
- 2013网易技术类笔试题(java开发方向+移动平台开发)
针叶: 感觉大公司的笔试面试就是另一种方式的计算机考研。
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
sinat_38268159: @aliangshuang:谢谢层主!
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
落叶伤剑: 如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别...
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
Marksinoberg: @pairsfish:date类型底层貌似是对long类型的数据的封装,也就是说JVM可能在编译的时...
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
Marksinoberg: @VirgoSoy:我觉得你总结的很好,很有道理。Java关于方法返回值应该就是对这个引用(或者基本...
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
飘零雁: catch 中有throw 的话,finally不会执行
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
baidu_35145522: 针对第一点,如果catch块中有System.exit(0);那么finally块是不会执行的。tr...
园龄:6年8个月
粉丝:117
关注:4
我只是坚持我的兴趣。
有所专而多能,精于一而博学。
- 个人资料
- 访问:620521次
- 积分:4873
- 等级:
- 排名:第5919名
- 原创:39篇
- 转载:108篇
- 译文:4篇
- 评论:103条
kavensu
- 友情链接
- Parse
Strikingly(傻瓜式网页设计)
- 文章搜索
- 文章分类
- Android(45)
- Android 数据存储(2)
- Android 自定义UI控件(6)
- Android 进程与线程(2)
- Android 多媒体(3)
- Android 编程规范(2)
- PHP(1)
- Java(19)
- Web 开发(4)
- 随笔(3)
- 创业(1)
- 软件安装及配置(9)
- 有启发的时文(5)
- 算法(9)
- 计算机网络(9)
- Epub(3)
- 其他(6)
- 操作系统(3)
- 编译原理(1)
- UML(1)
- 笔试面试题(6)
- C#开发(3)
- JavaScrip & Node.js(5)
- Git(1)
- 文章存档
- 2016年05月(1)
- 2016年04月(1)
- 2015年01月(1)
- 2014年01月(10)
- 2013年11月(1)
- 阅读排行
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)(133862)
- 邮件协议POP3/IMAP/SMTP服务的区别(57078)
- 【使用线程池的好处】多线程的环境中,尽量采用线程池(25782)
- TableLayout和TableRow的使用(18333)
- C#中SQL语句的参数写法(17579)
- 使用HttpClient通过POST方式发送XML,使用TCP/IP Monitor观察数据(16685)
- javascript 对象数组排序(15445)
- node.js常用模块(15132)
- onContextItemSelected 与 onMenuItemSelected 的那些事(14486)
- OSI的七层模型,网线,网卡,集线器,交换机,路由器分别工作在七层模型中的哪一层?(13713)
- 评论排行
- 2013网易技术类笔试题(java开发方向+移动平台开发)(30)
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)(28)
- onContextItemSelected 与 onMenuItemSelected 的那些事(6)
- 使用ActivityGroup时,在Activity中显示对话框出现的问题(5)
- 条码扫描二维码扫描——ZXing android(4)
- 网页分页数据抓取的几种方式(3)
- 网上下载图片并保持到SD卡中+读取SD卡中的图片(2)
- 【使用线程池的好处】多线程的环境中,尽量采用线程池(2)
- Android中Fragment的应用(android官方教程完美翻译)(2)
- 用点画分隔线(2)
- 推荐文章
- * CSDN日报20170828——《4个方法快速打造你的阅读清单》
- * CSDN博客模板调查问卷
- * 秒杀系统的一点思考
- * TCP网络通讯如何解决分包粘包问题
- * 技术与技术人员的价值
- * GitChat·人工智能 | 除了深度学习,机器翻译还需要啥?
- 最新评论
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
口袋本人: @mochounv:会执行的,建议你去实践一下。
- 【使用线程池的好处】多线程的环境中,尽量采用线程池
weixin_38310495: 666
- 【使用线程池的好处】多线程的环境中,尽量采用线程池
health7788: 厉害了
- 2013网易技术类笔试题(java开发方向+移动平台开发)
针叶: 感觉大公司的笔试面试就是另一种方式的计算机考研。
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
sinat_38268159: @aliangshuang:谢谢层主!
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
落叶伤剑: 如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别...
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
Marksinoberg: @pairsfish:date类型底层貌似是对long类型的数据的封装,也就是说JVM可能在编译的时...
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
Marksinoberg: @VirgoSoy:我觉得你总结的很好,很有道理。Java关于方法返回值应该就是对这个引用(或者基本...
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
飘零雁: catch 中有throw 的话,finally不会执行
- 有return的情况下try catch finally的执行顺序(最有说服力的总结)
baidu_35145522: 针对第一点,如果catch块中有System.exit(0);那么finally块是不会执行的。tr...
这是我的理解,或许存在误解欢迎指点。。。(*^__^*) 嘻嘻