2012-01-25 74 views
5

有人問我這樣一個問題:Java如何處理內存中的String對象?

String s = "abc"; // creates one String object and one 
      // reference variable 
In this simple case, "abc" will go in the pool and s will refer to it. 
String s = new String("abc"); // creates two objects, 
       // and one reference variable* 

基於上述細節多少String對象,多少參考變量之前,下面的代碼中的println語句創建?

String s1 = "spring "; 
String s2 = s1 + "summer "; 
s1.concat("fall "); 
s2.concat(s1); 
s1 += "winter "; 
System.out.println(s1 + " " + s2); 

我的回答是 這段代碼的結果是春冬春夏

有兩個引用變量,S1和S2。共有八個String對象 創建如下:「春天」,「夏天」(迷失),「春夏」,「秋天」(迷失),「春天 秋天」 (迷路),「冬天」(迷路),「春天的冬天」(此時「春天」丟失)。

八個字符串對象中只有兩個在此過程中不會丟失。

它是正確的嗎?

+0

好東西知道:http://stackoverflow.com/questions/7663252/java-string-concat-in-stringbuilder-call/請注意,我對這個問題的回答是錯誤的... – Gevorg

回答

3

答案是:2所引用和8個對象

String s1 = "spring "; //One reference and 1 object in string pool. (if it didn't exist already) 

String s2 = s1 + "summer "; //Two references and 3 objects 

s1.concat("fall "); //Two references and 5 objects 

s2.concat(s1); //Two references and 6 objects 

s1 += "winter "; //Two references and 8 objects 

System.out.println(s1 + " " + s2); 

現在你的問題:?如何在內存中的Java處理字符串對象

Java提供了兩種創建類String的對象的方法。

  1. String str1 =「OneString」;

在這種情況下,JVM搜索字符串池以查看是否存在等效字符串。如果是,則返回相同的引用。如果不是,則將其添加到字符串池並返回引用。 因此可能創建一個新對象或者可能不是。

  1. String str1 = new String(「OneString」);

現在,JVM必須在堆上創建一個對象。由於。如果OneString已經存在於字符串池中,則無關緊要。

你也可以把一個字符串池:

你可以叫實習生()的String對象。這會將String對象放入池中(如果它尚未存在),並將引用返回給池字符串。 (如果它已經在池中,它只是返回對已經存在的對象的引用)。

你可能想看看下面的鏈接:

What is the Java string pool and how is "s" different from new String("s")?

Questions about Java's String pool

1

看起來正確。這是一個SCJP考試問題btw。

concat返回一個新的String,這會丟失。 第一S1被覆蓋以「春冬」

兩件事情你應該知道的字符串中的Java:

乾杯 基督教

+0

您能否更多地評論_不是每次你寫新的String(「Summer」)一個全新的String ist construct_? 通過使用「new」,必須構造** new java.lang.String **對象(即兩個字符串在通過==比較時不相同)。但是,這兩個不同的String實例可以共享基礎char []數組(在特定條件下)。 –

+0

是的,我打字很快。你是對的,字符串對象被構造 - 我只是說「字符串」本身可能不需要更多的內存,因爲它在字符串池中。另請參閱:http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#intern() – Christian

1

字符串在java中是不可變的。有分配的字符數組和一些周圍的信息,如偏移量和長度。如果你使用字符串來初始化你的字符串,編譯器會嘗試優化併爲每個字面值創建一個字符串對象 - 這是可能的,因爲它們是不可變的。

如果你對字符串拼接或+,那麼新的字符串將被alloacted和數據compied一起(與性能損失

與此相反,創建子串出的幾乎是免費的 - 沒有數據將被複制

1
String s = "abc"; // creates one String object and one 
       // reference variable 

創建僅如果對象不存在已經是字符串常量池的一個字符串對象。

String s = new String("abc"); // creates two objects, 
           // and one reference variable* 

這實際上在堆中只創建一個對象。它將此對象添加到池中,當且僅當在此String對象上調用了intern()方法。

String s1 = "spring "; 
String s2 = s1 + "summer ";   
s1.concat("fall ");   
s2.concat(s1);   
s1 += "winter "; 
System.out.println(s1 + " " + s2); 

你的解釋似乎確定,除了你的System.out.println()多了一個字符串。:-)
當你說(丟失),它實際上意味着它是沒有更多的活的對象(參考沒有出現在堆棧上)。