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的四角恋的更多相关文章

  1. try catch finally return之间的关系

    一.try catch finally return之间的关系: 正在写dsoFramer的时候,同事突然说面试的时候问的一个问题,catch和return那个先执行,我瞬间迷茫了,然后整理了整理,稍 ...

  2. 异常 try catch finally return 执行关系 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. try catch finally return运行顺序

    首先让我们搞懂两组概念:try catch finally和return 1.try catch finally 首先说try catch, (1)try语句 ,try语句用来包围可能出现异常的代码片 ...

  4. Java_try,catch,finally return之间的执行顺序

    以往认为函数只要执行到return语句便会返回结果并终止,然而这时错误的,因为这存在特例. 掌握下面几条原则就可以完全解决“当try.catch.finally遭遇return”的问题. 原则:1.f ...

  5. java try catch finally return执行

    public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i ...

  6. 当try、catch中有return时,finally中的代码会执行么?

    今天,看到一个面试题: try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 我们用代码来验证下: public static void mai ...

  7. java-try catch中return在finally之前 还是之后执行

    finally语句在return语句执行之后return返回之前执行的. finally块中的return语句会覆盖try块中的return返回. 如果finally语句中没有return语句覆盖返回 ...

  8. C#:在catch中return,会执行finally吗?

    本文转自 vipxiaotian(CSDN) 请参考下面一段简单的语句块: 1:  try2:  {3:      throw new Exception("new exception&qu ...

  9. try catch finally return

    public override bool Start(IServerConfig config) { bool flag = true; listenSocket = new Socket(Liste ...

随机推荐

  1. 常用 NHibernate.Criterion

    Expression.Where<ScreenView>((v) => v.bizType != 0);

  2. tableview选择的时候不要cell的高亮显示样式

    1.若用方法: //-(BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)ind ...

  3. MVC 包命名规范

    action+form = model     actionservlet+struts-config.xml= controller     jsp+自定义标签=veiw 备注:这里说明的非常好 m ...

  4. Load$$ execution region symbols

    6.3.3 Load$$ execution region symbols The linker generates Load$$ symbols for every execution region ...

  5. Android 内存监测工具 DDMS --> Heap(转)

    DDMS 的全称是Dalvik Debug Monitor Service,它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息.Logcat.广播状态信息.模拟电话呼叫.接收 ...

  6. c语言_代码段_快说你是猪

    /* 项目:快说你是猪 作者:landv 时间:2014年3月12日 编译环境:VS2013 */ #pragma warning(disable:4996) //全部关掉 #pragma warni ...

  7. IIS:错误: 无法提交配置更改,因为文件已在磁盘上更改

    文件名: \\?\C:\Windows\system32\inetsrv\config\applicationHost.config 错误: 无法提交配置更改,因为文件已在磁盘上更改 通过 Micro ...

  8. Linux设置开机服务自动启动

    [root@localhost ~]# chkconfig --list     显示开机可以自动启动的服务[root@localhost ~]# chkconfig --add ***  添加开机自 ...

  9. Linux Shell 小脚本经典收藏

    原文:http://www.cnblogs.com/Javame/p/3867686.html 1.在两个文件中找出相同的号码 diff -y xx.txt oo.txt | egrep -v &qu ...

  10. Linux 解决 bash ./ 没有那个文件或目录 的方法

    在Debian 或 ubuntu 64位下运行 ./xxx 会跳出来说没有这个文件或者目录,但是ls看又有这个文件,很是奇怪. 其实原因很简单,是因为他没有32位的运行库 ia32-libs ,直接安 ...