重新認識Java finally

          關于java finally 網上有2篇文章個人認為相當不錯
          以下是轉貼內容:

          1 . JAVA finally字句的異常丟失和返回值覆蓋解析
          原帖地址 :
          http://blog.csdn.net/sureyonder/article/details/5560538
          轉貼
          Java虛擬機在每個try語句塊和與其相關的catch子句的結尾 處都會“調用”finally子句的子例程。實際上,finally子句在方法內部的表現(xiàn)很象“微型子例程”。finally子句正常結束后-指的是finally子句中最后一條語句正常執(zhí)行完畢,不包括拋出異常,或執(zhí)行return、continue、break等情況,隸屬于這個finally子句的微型子例程執(zhí)行“返回”操作。程序在第一次調用微型子例程的地方繼續(xù)執(zhí)行后面的語句。

          finally“微型子例程”不等同于方法函數(shù)的調用,finally子句都是在同一個棧內執(zhí)行的,微型子例程的“返回”操作也不會涉及到方法退棧,僅僅是使程序計數(shù)器pc跳轉到同一個方法的一個不同的位置繼續(xù)執(zhí)行。
          一 異常丟失
              public static void exceptionLost()  
               {  
                 try  
                 {  
                   try  
                   {  
                     throw new Exception( "exception in try" );  
                   }  
                   finally  
                   {  
                     throw new Exception( "exception in finally" );  
                   }  
                 }  
                 catch( Exception e )  
                 {  
                   System.out.println( e );  
                 }  
               }  

          exceptionLost()的輸出結果是“exception in finally”,而不是try塊中拋出的異常,這是JAVA異常機制的一個瑕疵-異常丟失。

          在字節(jié)碼中,throw語句不是原子性操作。在較老的JDK中,exceptionLost()中try塊的throw語句分解為幾步操作:
          1) 把Exception("exception in try")對象引用存儲到一個局部變量中
            astore_2  // pop the reference to the thrown exception, store into local variable 2
          2) 調用finally微型子程序
          3) 把局部變量中的Exception("exception in try")對象引用push到操作數(shù)棧頂,然后拋出異常
            aload_2  // push the reference to the thrown exception from local variable 2

            athrow   // throw the exception

          如果finally通過break、return、continue,或者拋出異常而退出,那么上面的第3步就不會執(zhí)行。

          在JDK1.6中,通過字節(jié)碼我們可以看到,finally子句作為一種特殊的catch來實現(xiàn)的,下面是exceptionLost()方法的異常表:

          Exception table:
            from   to   target  type
             0     10    10     any
           0     21    21     Class java/lang/Exception

          finally可以捕獲從0行到9行之間拋出的任何類型(any)的異常,并重新拋出捕獲的異常,或者拋出一個自己構造的新異常,這個新異常就會覆蓋try語句塊中的異常。
          二 返回值覆蓋

              public static int getValue()  
               {  
                 int value = 0;  
                   
                 try  
                 {  
                   value = 100;  
                     
                   return value;  
                 }  
                 finally  
                 {  
                   value = 200;  
                 }  
               }  

          這個方法的返回值是100還是200?結果是100。
          在字節(jié)碼中,return語句不是原子性操作,它會把getValue()中的return語句分解為幾步操作:
          1) 把value值存儲到一個局部變量(這里命名為temp)中:
             iload_0   // push local variable 0 - the 100
             istore_2   //  pop an int (the 100), store into local varaible 2
          2) 調用finally微型子程序
          3) 把局部變量(指temp)的值push到操作數(shù)棧頂,然后返回到調用方法
               iload_2  // push local varaible 2 - the 100
             ireturn      // return int on top of the stack - the 100: return 100

          由于return語句在返回之前會把返回值保存到一個臨時的局部變量中,所以在finally子句內對value重新賦值不會影響返回值。

          了解finally子句內在的一些知識,我們能夠了解finally能夠做什么和不能夠做什么,這樣會幫助我們正確使用finally子句。

          2 . 關于 Java 中 finally 語句塊的深度辨析
          原帖地址 :
          http://www.ibm.com/developerworks/cn/java/j-lo-finally/index.html?ca=drs-
          轉貼
          關于 Java 虛擬機是如何編譯 finally 語句塊的問題,有興趣的讀者可以參考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 節(jié) Compiling finally。那里詳細介紹了 Java 虛擬機是如何編譯 finally 語句塊。實際上,Java 虛擬機會把 finally 語句塊作為 subroutine(對于這個 subroutine 不知該如何翻譯為好,干脆就不翻譯了,免得產生歧義和誤解。)直接插入到 try 語句塊或者 catch 語句塊的控制轉移語句之前。但是,還有另外一個不可忽視的因素,那就是在執(zhí)行 subroutine(也就是 finally 語句塊)之前,try 或者 catch 語句塊會保留其返回值到本地變量表(Local Variable Table)中。待 subroutine 執(zhí)行完畢之后,再恢復保留的返回值到操作數(shù)棧中,然后通過 return 或者 throw 語句將其返回給該方法的調用者(invoker)。請注意,前文中我們曾經提到過 return、throw 和 break、continue 的區(qū)別,對于這條規(guī)則(保留返回值),只適用于 return 和 throw 語句,不適用于 break 和 continue 語句,因為它們根本就沒有返回值。

          posted on 2011-11-01 16:56 AK47 閱讀(840) 評論(0)  編輯  收藏 所屬分類: java相關

          <2011年11月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          導航

          統(tǒng)計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 西和县| 集贤县| 东宁县| 仁布县| 尼玛县| 南城县| 陇南市| 宿州市| 勐海县| 海阳市| 广东省| 屯门区| 兴城市| 江口县| 灵川县| 茌平县| 通州市| 佳木斯市| 五河县| 黑龙江省| 静乐县| 嘉义市| 当阳市| 绥芬河市| 陇南市| 武汉市| 博客| 潮州市| 兰坪| 西林县| 灵寿县| 利辛县| 叙永县| 莎车县| 中牟县| 昌乐县| 长垣县| 公安县| 蓬安县| 通城县| 东山县|