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

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

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

    Sky's blog

    我和我追逐的夢

    常用鏈接

    統計

    其他鏈接

    友情鏈接

    最新評論

    sun的java編譯器對string常量表達式的處理和優化

    首先把問題擺出來,先看這個代碼

    String a = "ab";
    String b = "a" + "b";
    System.out.println((a == b));

    打印結果會是什么?類似這樣的問題,有人考過我,我也拿來考過別人(蠻好玩的,大家也可以拿來問人玩),一般答案會是以下幾種:

    1.true
    "a" + "b" 的結果就是"ab",這樣a,b都是"ab"了,內容一樣所以"相等",結果true
    一般java新人如是答。
    2.false
    "a" + "a"會生成新的對象"aa",但是這個對象和String a = "ab";不同,(a == b)是比較對象引用,因此不相等,結果false
    對java的String有一定了解的通常這樣回答。
    3.true
    String a = "ab";創建了新的對象"ab"; 再執行String b = "a" + "b";結果b="ab",這里沒有創建新的對象,而是從JVM字符串常量池中獲取之前已經存在的"ab"對象。因此a,b具有對同一個string對象 的引用,兩個引用相等,結果true.
    能回答出這個答案的,基本已經是高手了,對java中的string機制比較了解。
    很遺憾,這個答案,是不夠準確的。或者說,根本沒有運行時計算b = "a" + "b";這個操作.實際上運行時只有String b = "ab";
    3的觀點適合解釋以下情況:
    String a = "ab";
    String b = "ab";
    System.out.println((a == b));
    如果String b = "a" + "b";是在運行期執行,則3的觀點是無法解釋的。運行期的兩個string相加,會產生新的對象的。(本文后面對此有解釋)

    4.true
    下面是我的回答:編譯優化+ 3的處理方式 = 最后的true
    String b = "a" + "b";編譯器將這個"a" + "b"作為常量表達式,在編譯時進行優化,直接取結果"ab",這樣這個問題退化
    String a = "ab";
    String b = "ab";
    System.out.println((a == b));
    然后根據3的解釋,得到結果true

    這里有一個疑問就是String不是基本類型,像
    int secondsOfDay = 24 * 60 * 60;
    這樣的表達式是常量表達式,編譯器在編譯時直接計算容易理解,而"a" + "b" 這樣的表達式,string是對象不是基本類型,編譯器會把它當成常量表達式來優化嗎?
    下面簡單證明我的推斷,首先編譯這個類:
    public class Test {
    private String a = "aa";
    }
    復制class文件備用,然后修改為
    public class Test {
    private String a = "a" + "a";
    }
    再次編譯,用ue之類的文本編輯器打開,察看二進制內容,可以發現,兩個class文件完全一致,連一個字節都不差.
    ok,真相大白了.根本不存在運行期的處理String b = "a" + "b";這樣的代碼的問題,編譯時就直接優化掉了。

    下面進一步探討,什么樣的string + 表達式會被編譯器當成常量表達式?
    String b = "a" + "b";
    這個String + String被正式是ok的,那么string + 基本類型呢?

    String a = "a1";
    String b = "a" + 1;
    System.out.println((a == b)); //result = true

    String a = "atrue";
    String b = "a" + true;
    System.out.println((a == b)); //result = true

    String a = "a3.4";
    String b = "a" + 3.4;
    System.out.println((a == b)); //result = true

    可見編譯器對string + 基本類型是當成常量表達式直接求值來優化的。

    再注意看這里的string都是"**"這樣的,我們換成變量來試試:
    String a = "ab";
    String bb = "b";
    String b = "a" + bb;
    System.out.println((a == b)); //result = false
    這個好理解,"a" + bb中的bb是變量,不能進行優化。這里很很好的解釋了為什么3的觀點不正確,如果String+String的操作是在運行時進行的,則會產生新的對象,而不是直接從jvm的string池中獲取。

    再修改一下,把bb作為常量變量:
    String a = "ab";
    final String bb = "b";
    String b = "a" + bb;
    System.out.println((a == b)); //result = true
    竟然又是true,編譯器的優化好厲害啊,呵呵,考慮下面這種情況:
    String a = "ab";
    final String bb = getBB();
    String b = "a" + bb;
    System.out.println((a == b)); //result = false
    private static String getBB() {
    return "b";
    }
    看來java(包括編譯器和jvm)對string的優化,真的是到了極點了,string這個所謂的"對象",完全不可以看成一般的對象,java對string的處理近乎于基本類型,最大限度的優化了幾乎能優化的地方。不過只在sun的java編譯器下測試過,還不清楚其他的java編譯器是否會同樣處理, 平時開發不接觸,懶得去研究了.

    另外感嘆一下,string的+號處理,算是java語言里面唯一的一個"運算符重載"(接觸過c++的人對這個不會陌生)吧?

    posted on 2007-12-05 15:42 sky ao 閱讀(2612) 評論(16)  編輯  收藏 所屬分類: java

    評論

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-05 16:46 寒松

    牛,增長了知識。
    但不知道是否做過測試,在那個版本的jdk編譯才會有這樣的情況?我相信這樣的編譯優化是和版本有關的  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-05 16:56 飄然

    只在sun的java編譯器下測試過,還不清楚其他的java編譯器是否會同樣處理, 平時開發不接觸其他版本的java編譯器。  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-05 17:10 Edward's

    真牛!  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-05 19:35 mg12

    受教了.  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-05 21:27 cccp21

    牛!

    寒松問的版本應該是指sun的多少版本——1.4?1.5?1.6?  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-05 22:31 Matthew Chen

    最后的這個方法:
    private static String getBB() {
    return "b";
    }
    如果加上final應該會內聯吧,說不定還是可以的哦。  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-05 23:24 隔葉黃鶯

    String b = "a" + "b";
    這種優化功能一般編譯器都會具備的,用javap -c HelloWorld 就能看到生成的代碼

    好點的編譯器都會把 b = a * 8;編譯成 b = a<<3; 甚至把 a * 9 編譯成 a<<3+a

    說到
    String a = "ab";
    final String bb = "b"; 就是編譯器的內聯了、靜態聯編了。其實做java的不用太去關心這些問題,我一個做硬件的同學都說了,你們現在那些寫程序都不考慮內存,什么程序都這么占內存。其實我的關點是順手能做好的盡量做好,何必所有的事情都推向GC呢,我Review別人的代碼發現他們全用 new Long(0),而不是 Long.value(0) 來生成 Long 對象的。

    看我原來寫過這樣一個東西:拾談"用最有效率的方法算出2乘以8等於幾?" http://m.tkk7.com/Unmi/articles/124098.html,其實很無聊的。

    原來聽說過幾個俄羅斯的程序員往一個硬件上寫程序,容量太小,用匯編也擠不下去,后來就直接用 HEX 代碼來寫了。  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-06 10:22 千里冰封

    太牛了  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2007-12-08 05:57 roygbip

    好文,受教!  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化[未登錄] 2007-12-29 17:17 菜鳥

    真正的高手。多謝!  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2008-01-15 10:24 愛上鳥的魚

    學習!感謝!  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2009-07-09 09:51 小人物

    學習了。真是好文章!  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化[未登錄] 2009-07-22 22:38 YODA

    研究的很有意思,看來是花了心思琢磨了
    不過,通常情況下我們不會真正的去寫一些對編譯器優化這么依賴的代碼.  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2009-09-10 17:34 三人行,必有我師焉

    String a = "ab";
    String b = "a" + "b";
    String c = "a";
    String d = "b";
    String e = c + d;
    System.out.println( ( a == b ) );
    System.out.println( ( a == e ) );

    呵呵,看看結果……  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2009-11-08 22:56 martree

    請問
    “a”.toLowerCase()=="a"//true
    "a"+"b".toLowerCase()=="ab"//false
    如何解釋,編譯器如何做的優化  回復  更多評論   

    # re: sun的java編譯器對string常量表達式的處理和優化 2009-11-10 10:15 sky ao

    “a”.toLowerCase()=="a"//true
    "a"+"b".toLowerCase()=="ab"//false

    這里沒有什么編譯器優化的問題,toLowerCase()是方法調用,其結果在運行期展開,編譯時沒有優化可言。

    1. 先看String.toLowerCase()方法,這個方法有個特殊的地方,如果字符串在調用之后內容沒有修改,則只是簡單的返回原有字符串的對象應用,而不是新建一個同樣內容的字符串。
    在你的例子中,運行時“a”.toLowerCase()返回的還是"a"的對象引用。

    3. "a"+"b".toLowerCase()的解釋就是這個表達式在運行期執行
    "a"+"b".toLowerCase() -> "a" + "b" -> "ab" ,注意"a" + "b"實在運行期執行,因此會產生一個新的字符串  回復  更多評論   

    主站蜘蛛池模板: 国产免费无遮挡精品视频| 国产成人亚洲综合网站不卡| 成全高清视频免费观看| 9久热精品免费观看视频| 亚洲91精品麻豆国产系列在线| 亚洲AV永久精品爱情岛论坛| 国产精品美女自在线观看免费| 国产精品视频免费观看| 久久成人免费大片| 精品一区二区三区免费观看| 在线视频亚洲一区| 亚洲日本VA午夜在线电影| 亚洲经典在线中文字幕| 久久久久无码精品亚洲日韩 | 日韩精品一区二区亚洲AV观看| 亚洲精品网站在线观看不卡无广告| 妞干网在线免费视频| 2021久久精品免费观看| 亚洲免费观看在线视频| 日韩成人免费视频| 99久久国产精品免费一区二区| 美女被羞羞网站免费下载| 色偷偷亚洲第一综合| 在线观看日本亚洲一区| 亚洲av无码一区二区三区天堂古代 | 亚洲乱亚洲乱妇无码麻豆| 国产L精品国产亚洲区久久| 免费真实播放国产乱子伦| 日韩在线天堂免费观看| 妞干网免费视频在线观看| 妞干网在线免费视频| 成人免费无码大片a毛片软件 | 亚洲AV综合色区无码另类小说| a级亚洲片精品久久久久久久| AV在线亚洲男人的天堂| 久久国产成人亚洲精品影院| 国外亚洲成AV人片在线观看| 亚洲色婷婷一区二区三区| 亚洲av无码乱码国产精品fc2| 久久久久亚洲AV无码专区首| 亚洲网站在线观看|