zoukankan      html  css  js  c++  java
  • 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

    可惜。。。字节码没看懂啊。。。唉。。。留帖,以后再说吧。唉。。

  • 相关阅读:
    synchronized一个(二)
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout
    NTFS簇大小对硬盘性能的影响测试
    Win10 开机自动打开上次未关闭程序怎么办
    Win10快速访问怎么关闭?
    激活windows 10 LTSC 2019(无需工具)
    WPS文字双行合一
    插入百度地图代码后,页面文字不能被选中的解决方案
    WPS文字批量选中整行(以第?章为例)
  • 原文地址:https://www.cnblogs.com/babybluevino/p/3652517.html
Copyright © 2011-2022 走看看