java String 對象的建立問題

先看看下面的代碼html

public String makinStrings()
{
    String s = "Fred";
    s = s + "47";
    s = s.substring(2, 5);
    s = s.toUpperCase();
    return s.toString();
}

問:調用makinStrings方法會建立幾個String對象呢。 答案:4個java

上面的方法有五條語句:如今讓咱們來一條一條分析一下。

String s = "Fred"; 結論:建立了一個String對象windows

這條語句至關於String s = new String("Fred"); 所以,毫無疑問,第一條語句建立了一個String對象,我想沒有有疑問吧?app

s = s + "47"; 結論:未建立String對象工具

這條語句也許不少人認爲是建立了String對象,我一開始也是這麼認爲的。可是爲了驗證個人想法。決定 用點法術恢復這條語句的原本面目。(有不少時候,編譯器老是在裏面搞一些小動做,javac.exe也不例外)優化

如今找到這個程序所生成的.class文件(假設是Test.class),找一個反編譯工具,我推薦JAD,能夠http://www.softpedia.com/progDownload/JAD-Download-85911.html下載 下載後,有一個jad.exe,將其路徑放到環境變量path中(只限windows)。並在.class文件的當前路徑執行以下的命令:ui

jad Testthis

而後大喊一聲「還我原本面目」code

會在當前目錄下生成一個Test.jad文件,打開它,文件內容以下:htm

public String makinStrings()
{
    String s = "Fred";
    s = (new StringBuilder(String.valueOf(s))).append("47").toString();
    s = s.substring(2, 5);
    s = s.toUpperCase();
    return s.toString();
}


哈哈,其餘的語句都沒變,只有第二條變長了,雖然多了個new,可是創建的是StringBuilder對象。原來

這是java編譯器的優化處理。原則是能不建String對象就不建String對象。而是用StringBuilder對象 加這些字符串鏈接起來,至關於一個字符串隊列。這種方式尤爲被使用在循環中,你們能夠看看下面的代碼: String s = ""; for(int i=0; i < 10000000; i++) s += "aa"; 沒有哪位老大認爲這是創建了10000000個String對象吧。但不幸的是,上面的代碼雖然沒有創建10000000個String對象 但卻創建了10000000個StringBuilder對象,那是爲何呢,自已用jad工具分析一下吧。 正確的寫法應該是:

StringBuilder sb = new StringBuilder("");
    for(int i=0; i < 10000000; i++)
        sb.append(String.valueOf(i));

s = s.substring(2, 5); 結論:建立了一個String對象 也許有不少人一開始就認爲這條語句是建立了一個String對象,那麼恭喜你,這條語句確實建立了一個String對象 實際上就是substring方法建立了一個String對象。這也沒什麼複雜的,自已下一個JDK源代碼,看看substring是如何實現的 就能夠知道了。我先說一下吧。先不用管substring是如何實現的,反正在substring方法返回時使用了一個new顯式地創建了一個String對象 不信本身看看源碼。 s = s.toUpperCase(); 結論:建立了一個String對象

toUpperCase()和substring方法相似,在返回時也是使用了new創建了一個String對象。

return s.toString(); 結論:建立String對象

toString方法返回的就是this,所以,它的返回值就是s。

這道題還算比較簡單,再給你們出一個更復雜一點的,也是關於String對象的建立的(只是改了一個原題)。

public String makinStrings()
{
    String s = "Fred";
    s = s + "Iloveyou.".substring(1).toLowerCase();
    s = s.substring(0);
    s = s.substring(0,1).toUpperCase();
    return s.toString();
}

先公佈答案吧,上述代碼也建立了4個String對象,哈哈!

爲何呢?

要想知道爲何,先得弄清楚substring、toLowerCase和toUpperCase何時建立String對象,何時不建立對象。

substring方法在截取的子字符串長度等於原字符串時,直接返回原字符串。並不建立新的String對象。

toLowerCase方法在字符串中更本沒有須要轉換的大寫字母時直接返回原字符串,如"abcd".toLowerCase()直接返回abcd,並不建立新的String對象

toUpperCase方法和toLowerCase相似。"ABCD".toUpperCase()直接返回ABCD。

知道了這個,上面的代碼就很是清楚了。

public String makinStrings()
{
    String s = "Fred";     // 建立一個String對象
    s = s + "Iloveyou.".substring(1).toLowerCase();  // substring(1)建立一個String對象,因爲toLowerCase()轉換的字符串是"loveyou.",沒有大寫字母,所以,它不建立新的String對象
    s = s.substring(0);   // 因爲substring(0)截獲的是s自己,所以,這條語句不建立新的String對象
    s = s.substring(0,1).toUpperCase();  // substring(0,1)建立了一個String對象,但因爲substring(0,1)的結果是"F",爲一個大寫字母,所以,toUpperCase直接返回"F"自己。
    return s.toString();
}
相關文章
相關標籤/搜索