<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.  回復  更多評論
      
    主站蜘蛛池模板: 亚洲成年看片在线观看| 亚洲美免无码中文字幕在线| 亚洲精品视频免费观看| 久久亚洲国产视频| 好爽…又高潮了毛片免费看| yellow视频免费在线观看| 中文字幕亚洲免费无线观看日本 | 欧洲 亚洲 国产图片综合| 免费v片在线观看| 久99久精品免费视频热77| 亚洲综合久久精品无码色欲| 成人亚洲性情网站WWW在线观看 | 亚洲JIZZJIZZ中国少妇中文| 丁香花在线视频观看免费| 亚洲成a人片在线观看精品| 亚洲成a人无码av波多野按摩| 免费成人激情视频| 一级做a爱过程免费视| 亚洲免费在线视频观看| 亚洲片一区二区三区| 无码国产精品一区二区免费虚拟VR | 国产亚洲福利一区二区免费看 | 99久久成人国产精品免费| 国产亚洲中文日本不卡二区| 久久亚洲国产中v天仙www | 亚洲乱码无人区卡1卡2卡3| 国产亚洲美女精品久久久久狼| 午夜网站免费版在线观看| 七色永久性tv网站免费看| 狠狠热精品免费观看| 亚洲一区二区久久| 亚洲AV无码码潮喷在线观看| 亚洲成a人片在线观看国产| 免费看国产成年无码AV片| 久久成人免费电影| sss在线观看免费高清| 国产亚洲精品美女| 亚洲欧美日韩中文字幕在线一区| 亚洲精品国产免费| 久久久久亚洲精品成人网小说| 亚洲精品线路一在线观看|