posts - 2,  comments - 0,  trackbacks - 0
          http://zangxt.javaeye.com/blog/421508

          try/catch/finally語句下,finally子句是肯定會執行的。但是很多人做不同的測試,卻得出了不同的結論。

          具體的原理最好是去看《深入java虛擬機》,里面對jsr、ret等幾個指令做了詳細的說明。這里不深入分析,而僅僅是從表現形式上看一下finally的特征。

          代碼:

            

          /*
          * author: Zang XT
          */

          public class TestFinal {
          public static void main(String[] args) {
          System.out.println("test1:" + testFinal1());
          System.out.println("test2:" + testFinal2());
          System.out.println("test3:" + testFinal3());
          System.out.println("test4:" + testFinal4());
          }

          static int testFinal1() {
          int i = 1;
          try {
          return i;
          } finally {
          System.out.println("in testFinal1():finally 肯定會被執行的!");
          i = 48;
          }
          }

          static String testFinal2() {
          String str = "try";
          try {
          return str;
          } finally {
          System.out.println("in testFinal2():finally 肯定會被執行的!");
          str = "finally";
          }
          }

          static StringBuilder testFinal3() {
          StringBuilder build = new StringBuilder("try ");
          try {
          return build;
          } finally {
          System.out.println("in testFinal3():finally 肯定會被執行的!");
          build.append("finally");
          build = new StringBuilder("你猜我是誰!");
          }
          }

          static String testFinal4() {
          try {
          return "return in try";
          } finally {
          System.out.println("in testFinal4():finally 肯定會被執行的!");
          return "return in finally";
          }
          }
          }

           

           

          輸出是:

          in testFinal1():finally 肯定會被執行的!

          test1:1

          in testFinal2():finally 肯定會被執行的!

          test2:try

          in testFinal3():finally 肯定會被執行的!

          test3:try finally

          in testFinal4():finally 肯定會被執行的!

          test4:return in finally

               結論很明顯,finally的語句確實執行了,而且肯定是在方法return之前執行的,而且,如果finally中有return語句的話,方法直接結 束。這里需要注意的只有一點:在try中的return語句會將返回結果值壓棧,然后轉入到finally子過程,等到finally子過程執行完畢之后 (沒有return),再返回。
          下面具體看4個例子:
                在testFinal1()中,return i;會將結果i的值,也就是1壓入棧。即使在finally中將i修改了(i=48),也不回對已經壓入棧里的1造成任何影響。
                在testFinal2()中,return str;將str的內容壓入棧,比如我們假設str的內容為0x108(只是一個地址值),通過這個地址值我們能找到"try",那棧里的內容就是 0x108。執行str = "finally",這時候str這個變量的內容可能變為0x237了,這是串"finally"的地址。方法調用結束后,返回的是什么?return時 壓入棧里的0x108。所以在打印結果時,我們打印的是通過0x108找到的字符串"try"。
                在testFinal3()中,return 壓棧的是build這個變量的值,比如是0x3579,通過這個值我們可以找到StringBuilder對象。finally語句塊中對這個對象的內容 進行了修改。build = new StringBuilder("你猜我是誰!");讓build變量指向了一個新的對象,這時候build的值可能是0x4579了。但是,別忘了,原來 的StringBuilder對象仍然在0x3579處,而我們壓棧的正是0x3579??!方法返回后,我們得到的返回值0x3579,通過這個引用值找 到相應的StringBuilder對象,所以打印的結果是test3:try finally。
                在testFinal4()中,finally有return語句,直接返回,方法結束。
                為什么不同的人有不同的結論?關鍵是沒有正確理解壓棧的是什么東西。其實初學java的時候,如果理解了變量是什么,并區分引用和對象本身就不會得到錯誤的結論了。再有,如果理解java中,方法調用都是采用傳值模式的話,這里也就類似的可以明白了。
          posted on 2009-09-28 11:09 iConnect 閱讀(131) 評論(0)  編輯  收藏 所屬分類: Java

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(2)

          文章分類(17)

          文章檔案(16)

          收藏夾(17)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 锦屏县| 日照市| 陇南市| 博爱县| 康保县| 澄迈县| 洪泽县| 清镇市| 武山县| 祁阳县| 锦屏县| 安康市| 三穗县| 贺兰县| 武山县| 镇坪县| 商南县| 峨眉山市| 科技| 大姚县| 唐河县| 罗源县| 泽库县| 临桂县| 五寨县| 眉山市| 合肥市| 新和县| 万年县| 英超| 靖安县| 应用必备| 谷城县| 洱源县| 隆化县| 黎川县| 增城市| 扶绥县| 延长县| 蓝田县| 南和县|