到底產生幾個String對象


幾個概念:

堆(heap):對象存放在堆中;當子程序結束運行時,對應的堆空間不會釋放。
棧(stack):基本類型和對象的應用存放在棧中;當子程序結束運行時,對應的棧空間會釋放。
方法區:與java堆一樣,是各個線程共享的內存區域,被描述為java堆的一個邏輯部分。
運行時常量池:是方法區的一部分。當常量池無法再申請到內存時會拋出OutOfMemoryError異常。
String常量池就是一個運行時常量池。常量池中的對象是可以共享的。

 

String a = "abc";
該語句創建對象的過程:先在常量池中查找是否有內容為"abc"的字符串對象,若有,直接將該對象的引用賦給a;若沒有,則在常量池中創建"abc"對象,再將其引用賦給a。


String a1 = new String("abc");
String a2 = new String("abc");
在常量池沒有"abc"對象的前提下,這兩條語句產生了3個對象,兩個處於堆中的string對象,一個處於字符串常量池string對象。

 

String a1 = "abc";
String a2 = "abc";
在常量池沒有"abc"對象的前提下,這兩條語句產生了一個對象,位於字符串常量池中。當String a1 = "abc"執行完畢后,JVM會在字符串常量池中創建一個"abc"對象;然后執行String a2 = "abc"時會先在常量池中查詢是否有"abc",如果有,將"abc"的引用賦給a2;如果沒有,在在字符串常量池中創建一個"abc"對象,再賦給a2。

 

String a1 = new String("abc");
String a2 = new String("abc");
String a3 = "abc";
String a4 = "abc";
在常量池沒有"abc"對象的前提下,這四條語句一共創建了三個對象。String a1 = new String("abc")分別在堆和常量池中創建了"abc"對象,然后String a2 = new String("abc")也在堆中創建了"abc"對象,String a3 = "abc"和String a4 = "abc"都是從常量池中獲取"abc"的引用。

 

String b1 = "abc";
String b2 = "ab";
String b3 = "ab" + "c";
String b4 = b2 + "c";
其中b1 = b3 ? true;b1 = b4 ? false。String b3 = "ab" + "c"會直接在常量池中查找"abc"對象,若存在,直接引用該對象。
而String b4 = b2 + "c"會生成新的對象,其內部實現是先new一個StringBuilder,然后 append(b2),append("c");然后讓b4引用toString()返回的對象。

String s = "aa" + "bb"這種形式是先將兩個字符串拼接起來,再在常量池中查找拼接過后的字符串對象("aabb");
String s1 = "aa";String s2 = s1 + "bb";這種形式是生成新的對象,這個對象內部實現是先new一個StringBuilder,
然后 append(s1),append("bb");然后讓s2引用toString()返回的對象。

 

String里面有一個方法:
public String intern()
返回字符串對象的規范化表示形式。 一個初始為空的字符串池,它由類 String 私有地維護。
當調用 intern 方法時,如果池已經包含一個等於此 String 對象的字符串(用 equals(Object) 方法確定),則返回池中的字符串。否則,將此 String 對象添加到池中,並返回此 String 對象的引用。
它遵循以下規則:對於任意兩個字符串 s 和 t,當且僅當 s.equals(t) 為 true 時,s.intern() == t.intern() 才為 true。 所有字面值字符串和字符串賦值常量表達式都使用 intern 方法進行操作。返回:

一個字符串,內容與此字符串相同,但一定取自具有唯一字符串的池。
例:
String str1 = "abbb";
String str2 = new String("abbb").intern();
System.out.println(str1==str2); //true

 

測試代碼

 1 public class TestString {  2     public static void main(String[] args) {  3         String s1 = new String("abc");  4         String s2 = "abc";  5         System.out.println("s1 = s2 ? " + (s1 == s2));  //false
 6         
 7         String a1 = new String("aaa");  8         String a2 = new String("aaa");  9         String a3 = "aaa"; 10         String a4 = "aaa"; 11         System.out.println("a1 = a2 ? " + (a1 == a2));  //false
12         System.out.println("a1 = a3 ? " + (a1 == a3));  //false
13         System.out.println("a3 = a4 ? " + (a3 == a4));    //true
14         
15         String b1 = "abcd"; 16         String b2 = "ab"; 17         String b3 = "ab" + "cd"; 18         String b4 = b2 + "cd"; 19         System.out.println("b1 = b3 ? " + (b1 == b3)); //true
20         System.out.println("b1 = b4 ? " + (b1 == b4)); //false
21         
22         String str1 = "abbb"; 23         String str2 = new String("abbb").intern(); 24         System.out.println("str1 = str2 ? " + (str1==str2));   //true
25  } 26 }

打印結果

s1 = s2 ? false a1 = a2 ? false a1 = a3 ? false a3 = a4 ? true b1 = b3 ? true b1 = b4 ? false str1 = str2 ? true

 

參考:http://www.cnblogs.com/devinzhang/archive/2012/01/25/2329463.html
   http://www.cnblogs.com/ydpvictor/archive/2012/09/09/2677260.html
         http://www.cnblogs.com/xiohao/p/4296088.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM