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. Openjudge-计算概论(A)-单词翻转

    描述: 输入一个句子(一行),将句子中的每一个单词翻转后输出. 输入只有一行,为一个字符串,不超过500个字符.单词之间以空格隔开.输出翻转每一个单词后的字符串,单词之间的空格需与原文一致. 样例输入 ...

  2. mvc路由参数注解

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); //过滤掉禁止访问的路由 routes.MapRoute( name: &quo ...

  3. SPOJ 705 New Distinct Substrings

    后缀数组.按照排序完的后缀一个一个统计.每一个后缀对答案做出的贡献为:n-SA[i]-height[i]. #pragma comment(linker, "/STACK:102400000 ...

  4. iOS UIApplication 里面各const实际用意

    //后台通知:屏幕操作通知等等 UIKIT_EXTERN NSString *const UIApplicationDidEnterBackgroundNotification       NS_AV ...

  5. python+appium使用记录

    最近在研究appium+appiumlibrary移动端的两个自动化测试库,特此将使用过程,粗略记录一下 1.环境搭建,略,自行百度. 2.查看apk包名及activity方法,自行百度. 3.基本步 ...

  6. C#中Bitmap类 对图像の操作 可检测图片完整性

    try { Bitmap bm = new Bitmap(pics[ip]); BitmapToBytes(bm).Reverse().Take(2); } catch (Exception ex) ...

  7. Codeforces Round #364 (Div. 2) D. As Fast As Possible

     D. As Fast As Possible time limit per test 1 second memory limit per test 256 megabytes input stand ...

  8. servlet第2讲(下集)----创建servlet实例(继承GenericServlet)

  9. differences between null pointer and void pointer.

    These are two different concepts, you cannot compare them. What the difference between the skunk and ...

  10. org.hibernate.exception.JDBCConnectionException: could not execute query

    最近在做一个项目,测试的时候是没有问题的,但是放到服务器上以后,第二天就会出现下面的异常.重启Tomcat服务器后就正常了,但是下一天还是会出现同样的异常..... 我就查了一些资料最终把问题给解决了 ...