2011-12-02 177 views
2

如果我有下面的代碼是可行的嗎?字符串訪問

String b = "abc"; 
String c = "def"; 
for (int i=0;i<100000000;i++){ 
    String a = b + c; // i got a different object , ahhh! 
} 

它是如何影響系統的?我們可以改進它,以及如何?

不會跟隨字符串池的概念,因爲我創建沒有新操作符的字符串我以1個對象結束,結果它創建100000000對象(我錯了)但我沒有unsendta如何(檢查與==運營商)

例如

final String b = "abc"; 
final String c = "def"; 
for (int i=0;i<100000000;i++){ 
    String a = b + c; //same object referred again and again 
} 

給同一個對象,我能請與==操作

不是T帽子這兩個例子都遵循String pool的概念嗎?爲什麼如果我有最終的我的字符串變量改變不同的對象或同一對象的結果。

+3

你想完成什麼? – Pieter

+0

不錯的一個:http://kaioa.com/node/59 – HRgiger

+0

這是一個面試問題,所以他檢查了這個人在String上得到了什麼,我無法得到最終的字符串變量和只是字符串變量的圖片。 – linkin

回答

6

如果bc都沒有標明final,編譯器可能假定在某一時刻在代碼中,可能會將不同的字符串分配給這些變量。因此,編寫a=b+c時,編譯器不能假設任何關於bc(它們甚至可能來自用戶)的內容,因此它必須連接它們併產生一個全新的字符串。

當他們final,編譯器可以知道肯定b總是​​和c總是"def",甚至可能推斷(b+c)=="abcdef",因此把它放在一個池或乾脆做串聯循環之前。

+0

您在運行時獲得的值將在String pool中保持(第一次),對不對?所以你怎麼能得到10000000個對象,而你只能得到1個對象,而這個對象只能被一次又一次地引用! – linkin

+0

爲什麼它不是從游泳池重複使用?在創建一次之後 – linkin

+1

如果通過'javap -c'運行你的類,你會發現在編寫'final'的情況下,編譯器把''abcdef''作爲一個常量。我不完全確定什麼時候把東西放在字符串池中,但我的猜測主要是指編譯時常量。我認爲,如果每個字符串都進入池中,那將會導致懲罰,因爲在檢查它已經在池中之前,您仍然必須創建字符串(如果這有意義的話)。 – Vlad

0

它是如何影響系統的?我們可以改進它,以及如何?

字符串是不可變的,即它每次連接時都會創建(或從池中重用)一個新的String對象。如果您正在循環連接,請使用StringBuilder對象。

String b = "abc"; 
String c = "def"; 
StringBuilder sb = new StringBuilder(); 
for (int i=0;i<100000000;i++){ 
    sb.append(b); 
    sb.append(c); 
} 
result = sb.toString(); 
0

「b」和「c」存儲在池中。但是每次創建「a」。使用StringBuilder來防止它。

只是爲了幫助你更好地理解

Object b = new Object(); //b created only once 
Object c = new Object(); //c created only once 

for(int i = 0; i < 100500; i++) { 
    MyClass a = new MyClass(b, c); //a created each loop 
} 

同樣的,字符串。

由於弗拉德提到的 - 在字符串的情況下,「B + C」將每次產生新的對象,如果它們不是最終

1

bc是最後的b + cconstant expression。這意味着+操作是在編譯名稱完成的。然後,將線equivallent到

String a = "abcdef"; 

b時和c是非最終,它們的值不再被視爲常量表達式和字符串連接是在運行時完成的,並創建新的字符串在每次迭代。