2014-02-05 28 views
3

數我碰到它正在創建一個查詢可繼續執行兩個代碼段傳來:字符串VS StringBuilder的對象

StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
stringBuilder.append("WHERE SALARY > ? "); 
stringBuilder.append("GROUP BY DEPT"); 

而且

String string = "SELECT * FROM EMPLOYEE " + 
"WHERE SALARY > ? " + 
"GROUP BY DEPT"; 

據我分析,這兩個片段創建4個物體。第一個片段創建一個StringBuilder對象和3個字符串對象,而第二個片段創建4個String對象。我的分析是否正確?

片段之一如何比片段2更有效?

+0

而且[這](http://stackoverflow.com/questions/21526747/how-many-string-objects-will-be-created-in-strings-sachintendulkar #21526786)和[this](http://stackoverflow.com/questions/11180866/how-many-string-objects-will-be-created-in-memory)和[this](http://stackoverflow.com /問題/ 10045147 /如何一對多的對象,是幸福創建)。多德... – avalancha

回答

8

你的第一個分析是正確的,但第二個片段只創建一個字符串對象。因爲它是一個字符串文字的編譯時間連接。

+1

很明顯,連接*可以在編譯時完成。但是,編譯器*是否有義務執行它? – NPE

+3

現在,當人們談論沒有android標籤的「java」時,假設它是熱點編譯器是安全的,然後就會發生。如果你建立你自己的編譯器,你不是沒有辦法編譯時間連接,因爲它仍然是功能正確的。 – Gimby

+1

@NPE根據[JLS§15.18.1](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.1)我不認爲編譯器有義務。 –

5

不完全是......

第一個版本創建1 StringBuilder每次執行和3個String常數(創建/ interned每一次啓動JVM)。當您通過stringBuilder.toString()使用該值時,它會在每次執行時創建另一個String對象。

第二個創建1 String常量(創建/ interned每JVM啓動一次),因爲整個級聯的值在編譯時已知。它相當於:

String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT"; 
0

字符串是不可變的,所以每次你做一個串聯(。運算符)時你都在內存中創建一個新的String對象。通過使用StringBuilder,您可以將文本添加到同一個對象,因此不需要創建新對象。

3

StringBuilder示例將創建4個對象。

第二個示例將只創建一個String對象。即使您連接了3個String文字,模型Java編譯器也足夠智能,可以檢測到您已連接了靜態String文字,因此會將其中的所有添加到一個文件中,並創建一個單一的String對象。

因此,

String string = "SELECT * FROM EMPLOYEE " + 
"WHERE SALARY > ? " + 
"GROUP BY DEPT"; 

是相同

String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT"; 
0

第一個代碼段創建1個對象。它在編譯時被連接在一起。

當您連接可變字符串時,StringBuilder具有更好的性能。例如,對於您的示例:

StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
if(salary > 0) { 
    stringBuilder.append("WHERE SALARY > ? "); 
} 
if(group == true) { 
    stringBuilder.append("GROUP BY DEPT"); 
} 

String string = "SELECT * FROM EMPLOYEE "; 
if(salary > 0) { 
    string = string + "WHERE SALARY > ? "; 
} 
if(group == true) { 
    string = = string + "GROUP BY DEPT"; 
}