2016-03-01 378 views
1

我知道當我們使用下面給出的字符串文字時,String對象在字符串池中創建(如果它不存在)。將爲String創建多少個對象?

String str1= "hello"; 
String str2= "hello"; 

在上面的例子中,只有一個字符串對象將在池中創建。

但是,當我們使用new關鍵字它總是在堆內存中創建一個新的String對象(即使有一個在字符串池)

String str3=new String("hello"); // here a new object will be created in heap. 

在這裏,我有一個關於許多對象如何將一個混亂在下面的情況下創建(池或堆內存)。

1) String s="Hello"; 
    String s1 = new String ("Hello"); 

2) String s = new String("Hello"); 
    String s1 = new String("Hello"); 

3) String s="Hello"; 
    String s1=new String (s); 

4) String s1 = new String ("Hello"); 
    String s="Hello"; 
+0

您是否試過閱讀JRE源代碼? –

回答

3

每次調用新的String(...)都會創建一個新的實例。您可以使用String.intern()從池中獲取實例。

String s="Hello"; 
String s1 = new String ("Hello"); 
System.out.println(System.identityHashCode(s)==System.identityHashCode(s1)); 


String si= new String ("Hello").intern(); 
String s1i = new String ("Hello").intern(); 
System.out.println(System.identityHashCode(si)==System.identityHashCode(s1i)); 

這將打印虛實

+0

是的,String x = new String(「Hello」)會在堆中創建一個新的實例,但是,如果我們不使用intern()方法,它是否會在Pool中創建一個新的String? – user3244519

1

我們可以佔內存在Java中的String對象以同樣的方式作爲 用於任何其他目的,除了走樣是字符串的常見。

標準字符串 實現有四個實例變量:對character array (8 bytes)three int values (4 bytes each)的引用。第一個int值是字符數組的偏移量; 第二個是count(字符串長度)。

String Object

在 圖上繪製有關的實例變量名的術語,即所表示的字符串由字符 值[偏移]通過值的[偏移+計數 - 1]。字符串 對象中的第三個int值是hash code,可在某些情況下保存重新計算。

因此,每個字符串對象總共使用40個字節(16個字節用於 對象內務操作,再加4個字節的每個由3個int實例變量加上 數組引用8個字節加上4個字節的填充)。

此空間要求是 字符本身所需的空間,它們位於數組中。字符所需的空間 單獨計算,因爲char數組通常在字符串之間共享 。由於String對象是不可變的,因此當String對象具有相同的基礎值[]時,這種安排允許實現 節省內存。 字符串值和子字符串。的長度N

的String通常使用用於 總共64個+ 2N字節40個字節(對於 字符串對象)加上24個2N字節(對於包含字符陣列)。但是,在字符串處理中使用子字符串是很典型的,而且 Java的表示方式允許我們在不必複製字符串字符的情況下這樣做!

來源:算法第四版

+1

你的描述已經過時了,它們改變了Java 7中的字符串表示形式。沒有'offset'和'count',字符串不能再共享它們的部分內容(子字符串)。 – MartinS

+0

@MartinS然後請編輯它以保持它的正確性! :) – OBX

0

多少對象正在爲你的例子創造出來的?

1) 4   
2) 4   
3) 3   
4) 4 

注意,每個String對象包含char - 陣列與字符串的內容。所以當創建一個新的String時,你實際上創建了兩個對象。

1)2)和4)

中的每一行的例子無論是創建其中包含char陣列(因此,我們有兩個對象游泳池String),或創建一個新的String它 - 再次 - 包含一個char-陣列。請注意,在這些示例中,字符串都不會共享任何內容。

3)

這個例子是不同的,因爲我們使用的第一String(2對象)來創建第二String。在這種情況下,第二個String將是一個新對象,但是它將使用與第一個相同的char陣列,因此不會創建新的對象。這導致總共只有3個對象,而不是4

再舉一個例子的

String s1 = "Hello"; 
String s2 = "Hello"; 

在這種情況下,我們將只有2個對象,因爲s1s2都指向同一個String與池中的對象相同char -array。