try...catch...finally...return的四角恋
java里的try...catch...finally的三角恋关系众多程序员必然是不陌生的。但是他们三者再加上一个return的话,就会难倒一大片人吧。以前就对这个知道这个问题,没系统的总结一下,结果今天女神把我问倒了。。so。。。。
下面就分别看一下吧!
case1:finally语句+try中有return:在执行到return的时候,会先执行finally里面的内容,然后再执行行try中的return。
@SuppressWarnings("finally")
static void test() {
int x = 1;
try {
logger.info("try.....");
return;
} finally {
++x;
logger.info("finally.....");
}
}
输出:
try.....
finally......
case2:case1+finally里也有return语句:try代码块中的return不执行,即在try中遇到return的时候,会先执行finally里面的内容(包括finally里面的return语句)。
public static void main(String[] args) {
logger.info(TryCatchDemo.test1());
}
@SuppressWarnings("finally")
static int test1() {
int x = 1;
try {
logger.info("try.....");
return x;
} finally {
x = x + 1;
logger.info("finally.....");
return x;
}
}
输出:
2014-04-08 16:39:23,311 INFO [TryCatchDemo.java:23] : try.....
2014-04-08 16:39:23,347 INFO [TryCatchDemo.java:27] : finally.....
2
好了,接下里是今天的重头戏了,就是偶被女神难倒的问题。
Case3:Important 我在try里return了某一个值,但是我在finally里对这个值进行了修改,那try块里返回的值是什么?先看代码。
public static void main(String[] args) {
logger.info(TryCatchDemo.test2());
}
@SuppressWarnings("finally")
static int test2() {
int x = 1;
try {
logger.info("try.....");
return x;
} finally {
++x;
logger.info("finally.....");
}
}
该代码会输出什么呢?按照我们正常的理解的话,先执行try里的语句,遇到return时候就去执行finally里的语句,然后修改了x的值为2,最后try里的return返回。
可是结果呢?
2014-04-08 16:45:37,548 INFO [TryCatchDemo.java:62] : try.....
2014-04-08 16:45:37,551 INFO [TryCatchDemo.java:66] : finally.....
2014-04-08 16:45:37,552 INFO [TryCatchDemo.java:16] : 1
结果输出的是1。说明finally里面对要返回的值进行修改,没有反应到最终的结果上去!如果是自己发现的问题的话,估计就到时为止了,下次记住就行了,可问这个问题的可是女神啊。so,屌丝决定看下这段代码编译出来的class对应的字节码,看虚拟机内部是如何执行的。
系统的环境是centos 6.4 x64
jdk环境见下图:

我们用javap -verbose TryCatchFinally >> TyrCatchFinally.txt 来把class文件字节码信息重定向到文件中。(javap是jdk自带的反编译工具命令)
这里主要是看test2部分的反编译字节码:
public int test2();
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=1
0: iconst_1 将整型常量1压入栈顶
1: istore_1 //将栈顶的整数出栈,并存入局部变量区的第2个变量
2: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
5: ldc #7 将字符串常量压入栈顶 // String try.....
7: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: iload_1 //将局部变量区的第2个变量压入栈
11: istore_2 //将栈顶的整数出栈,并存入局部变量区的第3个变量
12: iinc 1, 1
15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
18: ldc #9 // String finally.....
20: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: iload_2
24: ireturn
25: astore_3
26: iinc 1, 1
29: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
32: ldc #9 // String finally.....
34: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
37: aload_3
38: athrow
可惜。。。字节码没看懂啊。。。唉。。。留帖,以后再说吧。唉。。
try...catch...finally...return的四角恋的更多相关文章
- try catch finally return之间的关系
一.try catch finally return之间的关系: 正在写dsoFramer的时候,同事突然说面试的时候问的一个问题,catch和return那个先执行,我瞬间迷茫了,然后整理了整理,稍 ...
- 异常 try catch finally return 执行关系 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- try catch finally return运行顺序
首先让我们搞懂两组概念:try catch finally和return 1.try catch finally 首先说try catch, (1)try语句 ,try语句用来包围可能出现异常的代码片 ...
- Java_try,catch,finally return之间的执行顺序
以往认为函数只要执行到return语句便会返回结果并终止,然而这时错误的,因为这存在特例. 掌握下面几条原则就可以完全解决“当try.catch.finally遭遇return”的问题. 原则:1.f ...
- java try catch finally return执行
public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i ...
- 当try、catch中有return时,finally中的代码会执行么?
今天,看到一个面试题: try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 我们用代码来验证下: public static void mai ...
- java-try catch中return在finally之前 还是之后执行
finally语句在return语句执行之后return返回之前执行的. finally块中的return语句会覆盖try块中的return返回. 如果finally语句中没有return语句覆盖返回 ...
- C#:在catch中return,会执行finally吗?
本文转自 vipxiaotian(CSDN) 请参考下面一段简单的语句块: 1: try2: {3: throw new Exception("new exception&qu ...
- try catch finally return
public override bool Start(IServerConfig config) { bool flag = true; listenSocket = new Socket(Liste ...
随机推荐
- 解决XCode插件在XCode6.4上失效的办法
Xcode 6.4 解决 插件失效的方法 查看 插件目录: ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ 邮件打开插件 ...
- erlang四大behaviour之二-gen_fsm
来源:http://www.cnblogs.com/puputu/articles/1701012.html 今天介绍erlang的一个非常重要的behaviour,就是gen_fsm-有限状态机,有 ...
- 【开发笔记】java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor
在进行"spring的声明式事务管理配置"的时候,抛出该异常. 错误原因: 缺少aopalliance.jar包. 事务管理配置如下: <!-- #######5.sprin ...
- 线程池Executors探究
线程池用到的类在java.util.concurrent包下,核心类是Executors,通过其不同的几个方法可产生不同的线程池. 1.生成固定大小的线程池 public static Executo ...
- 在Scholarspace可视化交互式分析中遇到的几个问题及处理方法
1 JavaScript中的变量作用范围 JS中的变量作用域是以函数为单位的,因为在两个for循环中,不能用同一个变量命名作为循环的控制条件,不然会陷入死循环退出不来.曾经为了处理这个问题花看一天的时 ...
- 杭电OJ分类
基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.1032.1037.1040.1048.1056.1058.1 ...
- android 复制、粘贴文字
Android的剪切板(ClipboardManager) 注意:导包的时候 API 11之前: android.text.ClipboardManagerAPI 11之后: android.cont ...
- 关于LR监视Windows和linux的说明
一.监控windows系统: 1.监视连接前的准备工作 1)进入被监视windows系统,开启以下二个服务Remote Procedure Call(RPC) 和Remote Registry Ser ...
- JavaScript join() 方法
http://www.w3school.com.cn/jsref/jsref_shift.asp JavaScript Array 对象 定义和用法 join() 方法用于把数组中的所有元素放入一个字 ...
- 安装 nodejs
接下来使用npm命令安装express和socket.io 没有的话 用yum 安装一下 12 npm install --save expressnpm install --save socket. ...