dream.in.java

          能以不變應萬變是聰明人做事的準則。萬事從小事做起,積累小成功,問鼎大成功,是成功者的秘訣。

          用Javap反匯編幫你理解Java特性

          用Javap反匯編幫你理解Java特性

           

            Java 開發人員熟悉在一個循環中使用StringBuffer 來代替串聯 String 對象能獲得最佳性能。然而,多數開發人員從來沒有比較兩種方法產生的字節代碼的區別。在 Java 開發工具包(JDK)中有一個叫做 javap 的工具可以告訴你為什么這樣做可以獲得最佳性能。
            
            Javap 將一個類和它的方法的一些轉儲信息輸出到標準輸出。該工具不把代碼反編譯為 java 源代碼,但是它會把字節代碼反匯編成為由 Java 虛擬機規范定義的字節代碼指令。
            
            在你需要查看編譯器為你或者給你做了什么的時候,或者你想要看一處代碼的改動對編譯后的類文件有什么影響的時候,javap 相當有用。
            
            現在以我們前面提到的 StringBuffer 和 String 作為一個例子。下面是一個專門為例子設計的類,它有兩個方法,都返回一個由0到 n 的數字組成的 String,其中 n 由調用者提供。兩個方法唯一的區別在于一個使用 String 構建結果,另外一個使用 StringBuffer 構建結果。
            
            public class JavapTip {
            public static void main(String []args) {
            }
            private static String withStrings(int count) {
            String s = "";
            for (int i = 0; i < count; i++) { 中國網管論壇bbs.bitsCN.com
            s += i;
            }
            return s;
            }
            private static String withStringBuffer(int count) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < count; i++) {
            sb.append(i);
            }
            return sb.toString();
            }
            }
            
            現在讓我們看看對這個類使用?Cc 選項運行 javap 的輸出。-c 選項告訴 javap 反匯編在類中遇到的字節代碼。
            
            運行方式如下:
            
            >javap -c JavapTip
            
            此命令的輸出為:
            
            Method java.lang.String withStrings(int)
            0 ldc #2
            2 astore_1
            3 iconst_0
            4 istore_2
            5 goto 30
            8 new #3
            11 dup
            12 invokespecial #4
            15 aload_1
            16 invokevirtual #5
            19 iload_2
            20 invokevirtual #6
            23 invokevirtual #7
            26 astore_1
            27 iinc 2 1
            30 iload_2
            31 iload_0
            32 if_icmplt 8
            35 aload_1
            36 areturn
            Method java.lang.String withStringBuffer(int)
            0 new #3
            3 dup
            4 invokespecial #4 feedom.net
            7 astore_1
            8 iconst_0
            9 istore_2
            10 goto 22
            13 aload_1
            14 iload_2
            15 invokevirtual #6
            18 pop
            19 iinc 2 1
            22 iload_2
            23 iload_0
            24 if_icmplt 13
            27 aload_1
            28 invokevirtual #7
            31 areturn
            
            如果你以前沒有看過 Java 匯編器,那么這個輸出對你來說就會比較難懂,但是你應該可以看到 withString 方法在每次循環的時候都新創建了一個 StringBuffer 實例。然后它將已有的 String 的當前值追加到 StringBuffer 上,然后追加循環的當前值。最后,它對 buffer 調用 toString 并將結果賦給現有的 String 引用。
            
            withStringBuffer 方法與這個方法正好相反,在每次循環的時候 withStringBuffer 只調用現有 StringBuffer 的 append 方法,沒有創建新的對象,也沒有新的 String 引用。
            
            在這種情況下,我們已經知道了使用 StringBuffer 代替 String 是一種好的做法,但是如果我們不知道呢?那么 javap 可以幫助我們找到答案。在這里你可以看到更詳細的關于String,StringBuffer 的解釋
            
            你并不會經常需要一個 Java 反匯編器,但是當你需要的時候,知道你自己的機器已經有一個并且用法相當簡單的反匯編器當然是一件好事。如果你感興趣,看書看看 javap 的其它選項——或許你會發現在你的環境中需要的特性。

          posted on 2009-04-12 22:43 YXY 閱讀(142) 評論(0)  編輯  收藏


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


          網站導航:
           
          主站蜘蛛池模板: 桑植县| 嘉兴市| 卢湾区| 平乡县| 武邑县| 武乡县| 大冶市| 普安县| 定兴县| 霞浦县| 禄丰县| 昌宁县| 中卫市| 黑龙江省| 博白县| 阳春市| 中牟县| 永福县| 信阳市| 嘉兴市| 昌平区| 靖远县| 施秉县| 当涂县| 舟曲县| 天门市| 扎赉特旗| 湘西| 长葛市| 通化市| 凤冈县| 长宁区| 合川市| 河东区| 邓州市| 桑植县| 潼南县| 湛江市| 巴中市| 垫江县| 兴义市|