2014-02-05 29 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"; 
}