<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-46  評論-64  文章-2  trackbacks-0
    new & valueof & 直接賦值的區別
    首先來看下面這段代碼
    public static void main(String[] args) {
    ??String s1 = "s1";
    ??String s2 = new String("s2");
    ??String s3 = String.valueOf(12345);
    }
    ?
    編譯成class文件之后,使用eclipse class file viewer查看
    ?
    ? // Method descriptor #15 ([Ljava/lang/String;)V
    ? // Stack: 3, Locals: 4
    ? public static void main(java.lang.String[] args);
    ???? 0? ldc <String "s1"> [16]
    ???? 2? astore_1 [s1]

    ???? 3? new java.lang.String [18]
    ???? 6? dup
    ???? 7? ldc <String "s2"> [20]
    ???? 9? invokespecial java.lang.String(java.lang.String) [22]
    ??? 12? astore_2 [s2]
    ??? 13? sipush 12345
    ??? 16? invokestatic java.lang.String.valueOf(int) : java.lang.String [25]
    ??? 19? astore_3 [s3]

    ??? 20? return
    ????? Line numbers:
    ??????? [pc: 0, line: 12]
    ??????? [pc: 3, line: 13]
    ??????? [pc: 13, line: 14]
    ??????? [pc: 20, line: 20]
    ????? Local variable table:
    ??????? [pc: 0, pc: 21] local: args index: 0 type: java.lang.String[]
    ??????? [pc: 3, pc: 21] local: s1 index: 1 type: java.lang.String
    ??????? [pc: 13, pc: 21] local: s2 index: 2 type: java.lang.String
    ??????? [pc: 20, pc: 21] local: s3 index: 3 type: java.lang.String
    }
    ?
    對于第一行代碼 String s1 = "s1"; 編譯成字節碼之后,對應兩條指令,
    1. ldc指令從運行時常量池push一個值到Frame的操作數棧上面,這個值在這里就是"s1"字符串的引用,
    2. astore指令將objectref存儲到局部變量,這里也就是存儲到局部變量s1。
    ?
    對于第二行代碼???String s2 = new String("s2");編譯成字節碼之后,對于的指令也用高亮標注出來了,這里把操作數棧的情況畫了出來,希望能幫助理解。橙色標注的為棧頂元素。
    1. new指令會在堆上創建對象,操作數棧里壓入創建的objectref,
      ?
      objectref
      ...
    2. dup指令復制操作數棧頂的元素,?
      objectref
      objectref
      ...
    3. ldc指令依然是從常量池push一個值到Frame的操作數棧上,這個值是"s2"字符串的引用。?
      "s2"_ref
      objectref
      objectref
      ...
    4. invokespecial 指令調用一個方法,這里就是調用String的構造函數,調用完成之后棧上還有一個objectref?
      objectref
      ...
    5. astore指令將objectref存儲到局部變量,這里也就是存儲到局部變量s2。?
      ????????????
      ...
    ?
    對于第三行代碼??String s3 = String.valueOf(12345); 編譯成字節碼之后對應的指令,
    1. sipush 將 12345 壓棧
    2. invokestatic 調用 String.valueof(int) 方法
    3. astore 將棧頂的對象引用存儲到本地變量s3 (這里不再深究這個棧頂元素是怎么來的了)
    ?
    PMD檢查代碼的時候,有這樣的warning: Avoid instantiating?String objects.Call String.valueOf() instead. PMD給出的原因是In JDK 1.5, calling new String() causes memory allocation. String.valueOf() is more memory friendly.
    ?
    經過上面的分解,我們應該知道原因了,以后寫代碼的時候,初始化一個字符串,??String s1 = "s1"; 這樣的代碼肯定比??String s2 = new String("s2");代碼強,將其他類型的值轉換成String的時候,valueof方法比new方法效率也高。

    ?
    備注:
    A frame is used to store data and partial results(局部變量,操作數棧), as well as to perform dynamic linking , return values for methods, and dispatch exceptions.
    ?
    ldc指令的操作數棧: ...->...,value (value是int,float 或者 string 類型的引用)
    astore的操作數棧: ...,objectref->...
    new指令的操作數棧: ...->...,objectref
    dup指令的操作數棧: ...,value->...,value,value
    invokespecial的操作數棧: ...,objectref, [agr1,[arg2...]]->...
    invloestatic的操作數棧:..., [arg1, [arg2...]]?-> ...

    ?
    如果要理解的更透徹建議閱讀以下參考資料:
    posted on 2008-07-28 14:27 jht 閱讀(1704) 評論(1)  編輯  收藏 所屬分類: J2SE

    評論:
    # re: new & valueof & 直接賦值的區別 2008-07-28 23:29 | 隔葉黃鶯
    其實不用到字節碼里去,看 valueOf() 方法的源代碼大家就能明白是怎么回事,應該用 valueOf() 而不是 new.  回復  更多評論
      
    主站蜘蛛池模板: 欧美激情综合亚洲一二区| 日韩色视频一区二区三区亚洲 | 亚洲成在人线在线播放无码| 亚洲国产综合人成综合网站| 8090在线观看免费观看| 国产成人高清亚洲一区久久| 亚洲人成网www| 亚洲成AV人片在| 亚洲爆乳精品无码一区二区三区| 亚洲国产另类久久久精品黑人| 国产午夜亚洲不卡| 日本一道高清不卡免费| 国产色婷婷精品免费视频| 国产免费卡一卡三卡乱码| 香蕉97超级碰碰碰免费公| 成年女人A毛片免费视频| 亚洲人成无码网站在线观看| 久久亚洲精品无码| 亚洲天堂视频在线观看| 亚洲国产日韩女人aaaaaa毛片在线| 亚洲综合综合在线| 亚洲精品无码不卡在线播HE| 亚洲AV无码日韩AV无码导航| 久久久久亚洲精品日久生情| 亚洲一区二区三区久久| 亚洲bt加勒比一区二区| 亚洲性一级理论片在线观看| 最新亚洲精品国偷自产在线| 色播亚洲视频在线观看| 亚洲AV无码一区东京热久久 | 久久久久亚洲精品影视| 亚洲成a人片在线网站| 亚洲第一成年网站视频| 91av免费在线视频| 国产午夜亚洲精品不卡电影| 91av免费在线视频| 国产精品入口麻豆免费观看| 国产精品色午夜免费视频| 丁香五月亚洲综合深深爱| 亚洲中文字幕无码爆乳av中文| 久久久久亚洲AV成人无码|