天天看點

java字元串 指派語句_(轉)Java字元串

Java代碼

String str1="abc";

String str2="abc";

System.out.println(str1==str2);

則這段代碼結果就會是true。執行str1時,會首先檢查字元串池中是否存在"abc",如果有則直接賦給str1,如果沒有則在字元串池中建立一個"abc"然後再賦給str1,當執行到str2時,檢查字元串池已經存在了"abc",是以直接賦給str2,str1與str2指向同一個對象,是以結果為true。

而執行String str=new String("abc")時,不管字元串池中有沒有"abc"都會在堆中建立一個字元串對象然後将其賦給str引用。是以執行如下代碼

Java代碼

String str1=new String("abc");

String str2=new String("abc");

System.out.println(str1==str2);

結果就會為false,因為str1與str2指向的分别是兩個不同的對象。

Java代碼

String str1="abc";

String str2="def";

String str3=str1+str2;

System.out.println(str3=="abcdef");

//結果肯定是為false

因為str3指向堆中的"abcdef"對象,而"abcdef"是字元串池中的對象,因為結果為false。JVM對String str="abc"對象放在常量池中是在編譯時做的,而String str3=str1+str2是在運作時刻才能知道的。new對象也是在運作時才做的。而這段代碼總共建立了5個對象,字元串池中兩個、堆中三個。+運算符會在堆中建立來兩個String對象,也就是說從字元串池中複制這兩個值,然後在堆中建立兩個對象,然後再建立對象str3,然後将"abcdef"的堆位址賦給str3。

而如果

Java代碼

String str="abc"+"def";   //直接将"abcdef"放入字元串池中

System.out.println(str=="abcdef");

//結果為true

String str1="abc";

String str2=str1+"def";    //str1是在堆中建立的對象

System.out.println(str2=="abcdef");

//結果為false

由于字元串對象的大量使用(它是一個對象,一般而言對象總是在堆中配置設定記憶體),Java中為了節省記憶體空間和運作時間(如比較字元串時,==比equals()快),在編譯階段就把所有的字元串文字放到一個字元串池中,而運作時字元串池成為常量池的一部分。字元串池的好處,就是該池中所有相同的字元串常量被合并,隻占用一個空間。

我們知道,對兩個引用變量,使用==判斷它們的值(引用)是否相等,即指向同一個對象:

String s1 = "abc" ;

String s2 = "abc" ;

if( s1 == s2 ) System.out.println("s1,s2 refer to the same object");

else System.out.println("trouble");

這裡的輸出顯示,兩個字元串文字儲存為一個對象。就是說,上面的代碼隻在字元串中建立了一個String對象。

現在看String s = new String("abc");語句,這裡"abc"本身就是pool中的一個對象,而在運作時執行new String()時,将字元串池中的對象複制一份放到堆中,并且把堆中的這個對象的引用交給s持有。ok,這條語句就建立了2個String對象。

String s1 = new String("abc") ;

String s2 = new String("abc") ;

if( s1 == s2 ){ //不會執行的語句}

這時用==判斷就可知,雖然兩個對象的"内容"相同(equals()判斷),但兩個引用變量所持有的引用不同,上面的代碼建立了幾個String 對象? (3個,字元串池中1個,堆中2個。)